From 7f1de3626efdb6f378118bee3825e853841f409a Mon Sep 17 00:00:00 2001 From: Alexandre Pujol Date: Thu, 30 May 2024 14:23:56 +0100 Subject: [PATCH] feat(aa): handle appending value to defined variables. --- pkg/aa/resolve.go | 15 +++++++++ pkg/aa/resolve_test.go | 50 +++++++++++++++++++++-------- pkg/prebuild/directive/exec.go | 6 ++-- pkg/prebuild/directive/exec_test.go | 8 ++--- 4 files changed, 59 insertions(+), 20 deletions(-) diff --git a/pkg/aa/resolve.go b/pkg/aa/resolve.go index ec640de3..1b843f8b 100644 --- a/pkg/aa/resolve.go +++ b/pkg/aa/resolve.go @@ -29,6 +29,21 @@ func (f *AppArmorProfileFile) Resolve() error { // } // } + // Append value to variable + seen := map[string]*Variable{} + for idx, variable := range f.Preamble.GetVariables() { + if _, ok := seen[variable.Name]; ok { + if variable.Define { + return fmt.Errorf("variable %s already defined", variable.Name) + } + seen[variable.Name].Values = append(seen[variable.Name].Values, variable.Values...) + f.Preamble = f.Preamble.Delete(idx) + } + if variable.Define { + seen[variable.Name] = variable + } + } + // Resolve variables for _, variable := range f.Preamble.GetVariables() { newValues := []string{} diff --git a/pkg/aa/resolve_test.go b/pkg/aa/resolve_test.go index 8e4ff6b8..8b0a5597 100644 --- a/pkg/aa/resolve_test.go +++ b/pkg/aa/resolve_test.go @@ -110,14 +110,37 @@ func TestAppArmorProfileFile_resolveValues(t *testing.T) { func TestAppArmorProfileFile_Resolve(t *testing.T) { tests := []struct { name string - variables Rules + preamble Rules attachements []string want *AppArmorProfileFile wantErr bool }{ { - name: "firefox", - variables: Rules{ + name: "variables/append", + preamble: Rules{ + &Variable{Name: "lib", Values: []string{"/{usr/,}lib"}, Define: true}, + &Variable{Name: "multiarch", Values: []string{"*-linux-gnu*"}, Define: true}, + &Variable{Name: "exec_path", Values: []string{"@{lib}/DiscoverNotifier"}, Define: true}, + &Variable{Name: "exec_path", Values: []string{"@{lib}/@{multiarch}/{,libexec/}DiscoverNotifier"}, Define: false}, + }, + want: &AppArmorProfileFile{ + Preamble: Rules{ + &Variable{Name: "lib", Values: []string{"/{usr/,}lib"}, Define: true}, + &Variable{Name: "multiarch", Values: []string{"*-linux-gnu*"}, Define: true}, + &Variable{ + Name: "exec_path", Define: true, + Values: []string{ + "/{usr/,}lib/DiscoverNotifier", + "/{usr/,}lib/*-linux-gnu*/{,libexec/}DiscoverNotifier", + }, + }, + }, + }, + wantErr: false, + }, + { + name: "attachment/firefox", + preamble: Rules{ &Variable{Name: "firefox_name", Values: []string{"firefox{,-esr,-bin}"}, Define: true}, &Variable{Name: "firefox_lib_dirs", Values: []string{"/{usr/,}/lib{,32,64}/@{firefox_name}", "/opt/@{firefox_name}"}, Define: true}, &Variable{Name: "exec_path", Values: []string{"/{usr/,}bin/@{firefox_name}", "@{firefox_lib_dirs}/@{firefox_name}"}, Define: true}, @@ -155,8 +178,8 @@ func TestAppArmorProfileFile_Resolve(t *testing.T) { wantErr: false, }, { - name: "chromium", - variables: Rules{ + name: "attachment/chromium", + preamble: Rules{ &Variable{Name: "name", Values: []string{"chromium"}, Define: true}, &Variable{Name: "lib_dirs", Values: []string{"/{usr/,}lib/@{name}"}, Define: true}, &Variable{Name: "path", Values: []string{"@{lib_dirs}/@{name}"}, Define: true}, @@ -177,8 +200,8 @@ func TestAppArmorProfileFile_Resolve(t *testing.T) { wantErr: false, }, { - name: "geoclue", - variables: Rules{ + name: "attachment/geoclue", + preamble: Rules{ &Variable{Name: "libexec", Values: []string{"/{usr/,}libexec"}, Define: true}, &Variable{Name: "exec_path", Values: []string{"@{libexec}/geoclue", "@{libexec}/geoclue-2.0/demos/agent"}, Define: true}, }, @@ -206,8 +229,8 @@ func TestAppArmorProfileFile_Resolve(t *testing.T) { wantErr: false, }, { - name: "opera", - variables: Rules{ + name: "attachment/opera", + preamble: Rules{ &Variable{Name: "multiarch", Values: []string{"*-linux-gnu*"}, Define: true}, &Variable{Name: "name", Values: []string{"opera{,-beta,-developer}"}, Define: true}, &Variable{Name: "lib_dirs", Values: []string{"/{usr/,}lib/@{multiarch}/@{name}"}, Define: true}, @@ -234,12 +257,11 @@ func TestAppArmorProfileFile_Resolve(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := &AppArmorProfileFile{ - Profiles: []*Profile{{ - Header: Header{Attachments: tt.attachements}, - }}, + got := &AppArmorProfileFile{Preamble: tt.preamble} + if tt.attachements != nil { + got.Profiles = append(got.Profiles, &Profile{Header: Header{Attachments: tt.attachements}}) } - got.Preamble = tt.variables + if err := got.Resolve(); (err != nil) != tt.wantErr { t.Errorf("AppArmorProfileFile.Resolve() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/pkg/prebuild/directive/exec.go b/pkg/prebuild/directive/exec.go index 214c51b2..3bf89168 100644 --- a/pkg/prebuild/directive/exec.go +++ b/pkg/prebuild/directive/exec.go @@ -42,8 +42,10 @@ func (d Exec) Apply(opt *Option, profileRaw string) (string, error) { for name := range opt.ArgMap { profiletoTransition := util.MustReadFile(cfg.RootApparmord.Join(name)) dstProfile := aa.DefaultTunables() - err := dstProfile.Parse(profiletoTransition) - if err != nil { + if err := dstProfile.Parse(profiletoTransition); err != nil { + return "", err + } + if err := dstProfile.Resolve(); err != nil { return "", err } for _, variable := range dstProfile.Preamble.GetVariables() { diff --git a/pkg/prebuild/directive/exec_test.go b/pkg/prebuild/directive/exec_test.go index f21544c0..cd363bbc 100644 --- a/pkg/prebuild/directive/exec_test.go +++ b/pkg/prebuild/directive/exec_test.go @@ -31,8 +31,8 @@ func TestExec_Apply(t *testing.T) { Raw: " #aa:exec DiscoverNotifier", }, profile: ` #aa:exec DiscoverNotifier`, - want: ` @{lib}/@{multiarch}/{,libexec/}DiscoverNotifier Px, - @{lib}/DiscoverNotifier Px,`, + want: ` /{,usr/}lib{,exec,32,64}/*-linux-gnu*/{,libexec/}DiscoverNotifier Px, + /{,usr/}lib{,exec,32,64}/DiscoverNotifier Px,`, }, { name: "exec-unconfined", @@ -45,8 +45,8 @@ func TestExec_Apply(t *testing.T) { Raw: " #aa:exec U polkit-agent-helper", }, profile: ` #aa:exec U polkit-agent-helper`, - want: ` @{lib}/polkit-[0-9]/polkit-agent-helper-[0-9] Ux, - @{lib}/polkit-agent-helper-[0-9] Ux,`, + want: ` /{,usr/}lib{,exec,32,64}/polkit-[0-9]/polkit-agent-helper-[0-9] Ux, + /{,usr/}lib{,exec,32,64}/polkit-agent-helper-[0-9] Ux,`, }, } for _, tt := range tests {