diff --git a/pkg/aa/base.go b/pkg/aa/base.go index ed12a1d7c..7b2bb127a 100644 --- a/pkg/aa/base.go +++ b/pkg/aa/base.go @@ -4,7 +4,9 @@ package aa -import "strings" +import ( + "strings" +) type RuleBase struct { IsLineRule bool diff --git a/pkg/aa/capability.go b/pkg/aa/capability.go index f458350aa..46450e453 100644 --- a/pkg/aa/capability.go +++ b/pkg/aa/capability.go @@ -4,6 +4,9 @@ package aa +import ( + "slices" +) const tokCAPABILITY = "capability" diff --git a/pkg/aa/dbus.go b/pkg/aa/dbus.go index aa88266cb..ea88e5381 100644 --- a/pkg/aa/dbus.go +++ b/pkg/aa/dbus.go @@ -4,6 +4,10 @@ package aa +import ( + "slices" +) + const tokDBUS = "dbus" type Dbus struct { diff --git a/pkg/aa/file.go b/pkg/aa/file.go index 8aabd577a..4facc57a3 100644 --- a/pkg/aa/file.go +++ b/pkg/aa/file.go @@ -4,6 +4,17 @@ package aa +import ( + "slices" + "strings" +) + +const ( + tokLINK = "link" + tokOWNER = "owner" +) + + type File struct { RuleBase Qualifier diff --git a/pkg/aa/io_uring.go b/pkg/aa/io_uring.go index 4f76354c0..9ad2829a8 100644 --- a/pkg/aa/io_uring.go +++ b/pkg/aa/io_uring.go @@ -4,6 +4,8 @@ package aa +import "slices" + const tokIOURING = "io_uring" diff --git a/pkg/aa/mqueue.go b/pkg/aa/mqueue.go index 92a2252ce..e00aedb7f 100644 --- a/pkg/aa/mqueue.go +++ b/pkg/aa/mqueue.go @@ -5,6 +5,7 @@ package aa import ( + "slices" "strings" ) diff --git a/pkg/aa/network.go b/pkg/aa/network.go index 36ef3ac07..f8a286e3c 100644 --- a/pkg/aa/network.go +++ b/pkg/aa/network.go @@ -4,6 +4,8 @@ package aa +import "slices" + const tokNETWORK = "network" diff --git a/pkg/aa/profile.go b/pkg/aa/profile.go index 956a79221..8ad9e2a1d 100644 --- a/pkg/aa/profile.go +++ b/pkg/aa/profile.go @@ -131,7 +131,7 @@ func (p *Profile) Format() { if letterI != letterJ { // Add a new empty line between Files rule of different type hasOwnerRule = false - p.Rules = append(p.Rules[:i], append([]Rule{&RuleBase{}}, p.Rules[i:]...)...) + p.Rules = append(p.Rules[:i], append(Rules{nil}, p.Rules[i:]...)...) } } } diff --git a/pkg/aa/profile_test.go b/pkg/aa/profile_test.go index 26ea63165..c2edd52c6 100644 --- a/pkg/aa/profile_test.go +++ b/pkg/aa/profile_test.go @@ -82,3 +82,53 @@ func TestProfile_AddRule(t *testing.T) { }) } } + +func TestProfile_GetAttachments(t *testing.T) { + tests := []struct { + name string + Attachments []string + want string + }{ + { + name: "firefox", + Attachments: []string{ + "/{usr/,}bin/firefox{,-esr,-bin}", + "/{usr/,}lib{,32,64}/firefox{,-esr,-bin}/firefox{,-esr,-bin}", + "/opt/firefox{,-esr,-bin}/firefox{,-esr,-bin}", + }, + want: "/{{usr/,}bin/firefox{,-esr,-bin},{usr/,}lib{,32,64}/firefox{,-esr,-bin}/firefox{,-esr,-bin},opt/firefox{,-esr,-bin}/firefox{,-esr,-bin}}", + }, + { + name: "geoclue", + Attachments: []string{ + "/{usr/,}libexec/geoclue", + "/{usr/,}libexec/geoclue-2.0/demos/agent", + }, + want: "/{{usr/,}libexec/geoclue,{usr/,}libexec/geoclue-2.0/demos/agent}", + }, + { + name: "null", + Attachments: []string{}, + want: "", + }, + { + name: "empty", + Attachments: []string{""}, + want: "", + }, + { + name: "not valid aare", + Attachments: []string{"/file", "relative"}, + want: "/{file,relative}", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &Profile{} + p.Attachments = tt.Attachments + if got := p.GetAttachments(); got != tt.want { + t.Errorf("Profile.GetAttachments() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/aa/ptrace.go b/pkg/aa/ptrace.go index 5a014bc74..a8ac55fc5 100644 --- a/pkg/aa/ptrace.go +++ b/pkg/aa/ptrace.go @@ -4,6 +4,8 @@ package aa +import "slices" + const tokPTRACE = "ptrace" type Ptrace struct { diff --git a/pkg/aa/signal.go b/pkg/aa/signal.go index 9a6da9350..7daaa9a89 100644 --- a/pkg/aa/signal.go +++ b/pkg/aa/signal.go @@ -4,6 +4,7 @@ package aa +import "slices" const tokSIGNAL = "signal" diff --git a/pkg/aa/template.go b/pkg/aa/template.go index 4f433c091..c0b741480 100644 --- a/pkg/aa/template.go +++ b/pkg/aa/template.go @@ -40,7 +40,7 @@ var ( tokINCLUDE, tokRLIMIT, tokCAPABILITY, tokNETWORK, tokMOUNT, tokPIVOTROOT, tokCHANGEPROFILE, tokSIGNAL, tokPTRACE, tokUNIX, tokUSERNS, tokIOURING, - tokDBUS, "file", + tokDBUS, "file", "variable", }) // convert apparmor requested mask to apparmor access mode @@ -73,7 +73,7 @@ var ( "profile", "include_if_exists", } - ruleWeights = map[string]int{} + ruleWeights = make(map[string]int, len(ruleAlphabet)) // The order the apparmor file rules should be sorted fileAlphabet = []string{ @@ -98,8 +98,9 @@ var ( "@{PROC}", // 10. Proc files "/dev", // 11. Dev files "deny", // 12. Deny rules + "profile", // 13. Subprofiles } - fileWeights = map[string]int{} + fileWeights = make(map[string]int, len(fileAlphabet)) ) func generateTemplates(names []string) map[string]*template.Template { diff --git a/pkg/aa/unix.go b/pkg/aa/unix.go index 3c53dc84e..f5915f018 100644 --- a/pkg/aa/unix.go +++ b/pkg/aa/unix.go @@ -4,6 +4,8 @@ package aa +import "slices" + const tokUNIX = "unix" type Unix struct {