feat(aa-log): minor improvment in rule generation & formatting.

This commit is contained in:
Alexandre Pujol 2024-09-26 22:15:46 +01:00
parent fbdf9cea64
commit 83bc7d3ade
Failed to generate hash of commit
7 changed files with 97 additions and 34 deletions

View file

@ -9,8 +9,8 @@ import (
)
type Base struct {
IsLineRule bool
Comment string
IsLineRule bool
NoNewPrivs bool
FileInherit bool
Optional bool

View file

@ -118,6 +118,21 @@ func (r *File) String() string {
}
func (r *File) Validate() error {
if !isAARE(r.Path) {
return fmt.Errorf("'%s' is not a valid AARE", r.Path)
}
for _, v := range r.Access {
if v == "" {
continue
}
if !slices.Contains(requirements[r.Kind()]["access"], v) ||
!slices.Contains(requirements[r.Kind()]["transition"], v) {
return fmt.Errorf("invalid mode '%s'", v)
}
}
if r.Target != "" && !isAARE(r.Target) {
return fmt.Errorf("'%s' is not a valid AARE", r.Target)
}
return nil
}
@ -260,6 +275,12 @@ func (r *Link) String() string {
}
func (r *Link) Validate() error {
if !isAARE(r.Path) {
return fmt.Errorf("'%s' is not a valid AARE", r.Path)
}
if !isAARE(r.Target) {
return fmt.Errorf("'%s' is not a valid AARE", r.Target)
}
return nil
}

View file

@ -17,10 +17,10 @@ const (
func init() {
requirements[MOUNT] = requirement{
"flags": {
"acl", "async", "atime", "ro", "rw", "bind", "rbind", "dev",
"diratime", "dirsync", "exec", "iversion", "loud", "mand", "move",
"noacl", "noatime", "nodev", "nodiratime", "noexec", "noiversion",
"nomand", "norelatime", "nosuid", "nouser", "private", "relatime",
"ro", "rw", "acl", "async", "atime", "bind", "dev", "diratime",
"dirsync", "exec", "iversion", "loud", "mand", "move", "noacl",
"noatime", "nodev", "nodiratime", "noexec", "noiversion", "nomand",
"norelatime", "nosuid", "nouser", "private", "rbind", "relatime",
"remount", "rprivate", "rshared", "rslave", "runbindable", "shared",
"silent", "slave", "strictatime", "suid", "sync", "unbindable",
"user", "verbose",

View file

@ -495,9 +495,15 @@ func (r rule) String() string {
}
func isAARE(str string) bool {
return strings.HasPrefix(str, "@") ||
strings.HasPrefix(str, "/") ||
strings.HasPrefix(str, "\"")
if len(str) < 1 {
return false
}
switch str[0] {
case '@', '/', '"':
return true
default:
return false
}
}
// Convert a slice of internal rules to a slice of ApparmorRule.
@ -652,8 +658,8 @@ done:
}
// Parse apparmor profile rules by paragraphs
func ParseRules(input string) ([]Rules, []string, error) {
paragraphRules := []Rules{}
func ParseRules(input string) (ParaRules, []string, error) {
paragraphRules := ParaRules{}
paragraphs := []string{}
for _, match := range regParagraph.FindAllStringSubmatch(input, -1) {

View file

@ -139,16 +139,18 @@ func (p *Profile) GetAttachments() string {
var (
newLogMap = map[string]func(log map[string]string) Rule{
// class
"rlimits": newRlimitFromLog,
"cap": newCapabilityFromLog,
"io_uring": newIOUringFromLog,
"signal": newSignalFromLog,
"ptrace": newPtraceFromLog,
"namespace": newUsernsFromLog,
"unix": newUnixFromLog,
"dbus": newDbusFromLog,
"cap": newCapabilityFromLog,
"net": newNetworkFromLog,
"posix_mqueue": newMqueueFromLog,
"sysv_mqueue": newMqueueFromLog,
"signal": newSignalFromLog,
"ptrace": newPtraceFromLog,
"unix": newUnixFromLog,
"io_uring": newIOUringFromLog,
"dbus": newDbusFromLog,
"mount": func(log map[string]string) Rule {
if strings.Contains(log["flags"], "remount") {
return newRemountFromLog(log)
@ -156,7 +158,6 @@ var (
newRule := newLogMountMap[log["operation"]]
return newRule(log)
},
"net": newNetworkFromLog,
"file": func(log map[string]string) Rule {
if log["operation"] == "change_onexec" {
return newChangeProfileFromLog(log)
@ -164,14 +165,19 @@ var (
return newFileFromLog(log)
}
},
"exec": newFileFromLog,
"getattr": newFileFromLog,
"mkdir": newFileFromLog,
"mknod": newFileFromLog,
"open": newFileFromLog,
"rename_src": newFileFromLog,
"truncate": newFileFromLog,
"unlink": newFileFromLog,
// operation
"capable": newCapabilityFromLog,
"chmod": newFileFromLog,
"exec": newFileFromLog,
"getattr": newFileFromLog,
"link": newFileFromLog,
"mkdir": newFileFromLog,
"mknod": newFileFromLog,
"open": newFileFromLog,
"rename_dest": newFileFromLog,
"rename_src": newFileFromLog,
"truncate": newFileFromLog,
"unlink": newFileFromLog,
}
newLogMountMap = map[string]func(log map[string]string) Rule{
"mount": newMountFromLog,
@ -213,7 +219,7 @@ func (p *Profile) AddRule(log map[string]string) {
case strings.Contains(log["operation"], "dbus"):
p.Rules = append(p.Rules, newDbusFromLog(log))
default:
fmt.Printf("unknown log type: %s", log["operation"])
fmt.Printf("unknown log type: %s\n", log["operation"])
}
}
}

View file

@ -94,7 +94,7 @@ func (r Rules) Delete(i int) Rules {
}
func (r Rules) DeleteKind(kind Kind) Rules {
res := make(Rules, 0)
res := make(Rules, 0, len(r))
for _, rule := range r {
if rule == nil {
continue
@ -106,8 +106,8 @@ func (r Rules) DeleteKind(kind Kind) Rules {
return res
}
func (r Rules) Filter(filter Kind) Rules {
res := make(Rules, 0)
func (r Rules) FilterOut(filter Kind) Rules {
res := make(Rules, 0, len(r))
for _, rule := range r {
if rule == nil {
continue
@ -119,8 +119,21 @@ func (r Rules) Filter(filter Kind) Rules {
return res
}
func (r Rules) Filter(filter Kind) Rules {
res := make(Rules, 0, len(r))
for _, rule := range r {
if rule == nil {
continue
}
if rule.Kind() == filter {
res = append(res, rule)
}
}
return res
}
func (r Rules) GetVariables() []*Variable {
res := make([]*Variable, 0)
res := make([]*Variable, 0, len(r))
for _, rule := range r {
switch rule := rule.(type) {
case *Variable:
@ -131,7 +144,7 @@ func (r Rules) GetVariables() []*Variable {
}
func (r Rules) GetIncludes() []*Include {
res := make([]*Include, 0)
res := make([]*Include, 0, len(r))
for _, rule := range r {
switch rule := rule.(type) {
case *Include:
@ -247,3 +260,20 @@ func (r Rules) Format() Rules {
r.setPaddings(paddingsIndex, paddingsMaxLen)
return r
}
// ParaRules is a slice of Rules grouped by paragraph
type ParaRules []Rules
func (r ParaRules) Flatten() Rules {
totalLen := 0
for i := range r {
totalLen += len(r[i])
}
res := make(Rules, 0, totalLen)
for i := range r {
res = append(res, r[i]...)
}
return res
}

View file

@ -138,7 +138,7 @@ var (
// The order AARE should be sorted
stringAlphabet = []byte(
"!\"#$%&'*(){}[]+,-./:;<=>?@\\^_`|~0123456789abcdefghijklmnopqrstuvwxyz",
"!\"#$%&'*(){}[]@+,-./:;<=>?\\^_`|~0123456789abcdefghijklmnopqrstuvwxyz",
)
stringWeights = generateWeights(stringAlphabet)
@ -232,11 +232,11 @@ func cjoin(i any) string {
}
}
func kindOf(i any) string {
func kindOf(i Rule) string {
if i == nil {
return ""
}
return i.(Rule).Kind().String()
return i.Kind().String()
}
func setindent(i string) string {