feat(aa): add requirements map.

This commit is contained in:
Alexandre Pujol 2024-05-25 22:01:29 +01:00
parent e38f5b4637
commit 744c745394
Failed to generate hash of commit
14 changed files with 163 additions and 10 deletions

View file

@ -10,6 +10,21 @@ import (
const tokCAPABILITY = "capability" const tokCAPABILITY = "capability"
func init() {
requirements[tokCAPABILITY] = requirement{
"name": {
"audit_control", "audit_read", "audit_write", "block_suspend", "bpf",
"checkpoint_restore", "chown", "dac_override", "dac_read_search",
"fowner", "fsetid", "ipc_lock", "ipc_owner", "kill", "lease",
"linux_immutable", "mac_admin", "mac_override", "mknod", "net_admin",
"net_bind_service", "net_broadcast", "net_raw", "perfmon", "setfcap",
"setgid", "setpcap", "setuid", "sys_admin", "sys_boot", "sys_chroot",
"sys_module", "sys_nice", "sys_pacct", "sys_ptrace", "sys_rawio",
"sys_resource", "sys_time", "sys_tty_config", "syslog", "wake_alarm",
},
}
}
type Capability struct { type Capability struct {
RuleBase RuleBase
Qualifier Qualifier

View file

@ -6,6 +6,12 @@ package aa
const tokCHANGEPROFILE = "change_profile" const tokCHANGEPROFILE = "change_profile"
func init() {
requirements[tokCHANGEPROFILE] = requirement{
"mode": []string{"safe", "unsafe"},
}
}
type ChangeProfile struct { type ChangeProfile struct {
RuleBase RuleBase
Qualifier Qualifier

View file

@ -10,6 +10,16 @@ import (
const tokDBUS = "dbus" const tokDBUS = "dbus"
func init() {
requirements[tokDBUS] = requirement{
"access": []string{
"send", "receive", "bind", "eavesdrop", "r", "read",
"w", "write", "rw",
},
"bus": []string{"system", "session", "accessibility"},
}
}
type Dbus struct { type Dbus struct {
RuleBase RuleBase
Qualifier Qualifier

View file

@ -16,6 +16,16 @@ const (
tokSUBSET = "subset" tokSUBSET = "subset"
) )
func init() {
requirements[tokFILE] = requirement{
"access": {"m", "r", "w", "l", "k"},
"transition": {
"ix", "ux", "Ux", "px", "Px", "cx", "Cx", "pix", "Pix", "cix",
"Cix", "pux", "PUx", "cux", "CUx", "x",
},
}
}
type File struct { type File struct {
RuleBase RuleBase
Qualifier Qualifier

View file

@ -8,6 +8,11 @@ import "slices"
const tokIOURING = "io_uring" const tokIOURING = "io_uring"
func init() {
requirements[tokIOURING] = requirement{
"access": []string{"sqpoll", "override_creds"},
}
}
type IOUring struct { type IOUring struct {
RuleBase RuleBase

View file

@ -15,7 +15,18 @@ const (
tokUMOUNT = "umount" tokUMOUNT = "umount"
) )
) func init() {
requirements[tokMOUNT] = requirement{
"flags": {
"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", "ro", "rprivate",
"rshared", "rslave", "runbindable", "rw", "shared", "silent", "slave",
"strictatime", "suid", "sync", "unbindable", "user", "verbose",
},
}
}
type MountConditions struct { type MountConditions struct {
FsType string FsType string

View file

@ -11,6 +11,15 @@ import (
const tokMQUEUE = "mqueue" const tokMQUEUE = "mqueue"
func init() {
requirements[tokMQUEUE] = requirement{
"access": []string{
"r", "w", "rw", "read", "write", "create", "open",
"delete", "getattr", "setattr",
},
"type": []string{"posix", "sysv"},
}
}
type Mqueue struct { type Mqueue struct {
RuleBase RuleBase

View file

@ -4,10 +4,29 @@
package aa package aa
import "slices"
const tokNETWORK = "network" const tokNETWORK = "network"
func init() {
requirements[tokNETWORK] = requirement{
"access": []string{
"create", "bind", "listen", "accept", "connect", "shutdown",
"getattr", "setattr", "getopt", "setopt", "send", "receive",
"r", "w", "rw",
},
"domains": []string{
"unix", "inet", "ax25", "ipx", "appletalk", "netrom", "bridge",
"atmpvc", "x25", "inet6", "rose", "netbeui", "security", "key",
"netlink", "packet", "ash", "econet", "atmsvc", "rds", "sna", "irda",
"pppox", "wanpipe", "llc", "ib", "mpls", "can", "tipc", "bluetooth",
"iucv", "rxrpc", "isdn", "phonet", "ieee802154", "caif", "alg",
"nfc", "vsock", "kcm", "qipcrtr", "smc", "xdp", "mctp",
},
"type": []string{
"stream", "dgram", "seqpacket", "rdm", "raw", "packet",
},
"protocol": []string{"tcp", "udp", "icmp"},
}
}
type AddressExpr struct { type AddressExpr struct {
Source string Source string

View file

@ -8,6 +8,14 @@ import "slices"
const tokPTRACE = "ptrace" const tokPTRACE = "ptrace"
func init() {
requirements[tokPTRACE] = requirement{
"access": []string{
"r", "w", "rw", "read", "readby", "trace", "tracedby",
},
}
}
type Ptrace struct { type Ptrace struct {
RuleBase RuleBase
Qualifier Qualifier

View file

@ -9,6 +9,15 @@ const (
tokSET = "set" tokSET = "set"
) )
func init() {
requirements[tokRLIMIT] = requirement{
"keys": {
"cpu", "fsize", "data", "stack", "core", "rss", "nofile", "ofile",
"as", "nproc", "memlock", "locks", "sigpending", "msgqueue", "nice",
"rtprio", "rttime",
},
}
}
type Rlimit struct { type Rlimit struct {
RuleBase RuleBase

View file

@ -10,6 +10,8 @@ const (
tokDENY = "deny" tokDENY = "deny"
) )
type requirement map[string][]string
type constraint uint type constraint uint
const ( const (

View file

@ -8,6 +8,27 @@ import "slices"
const tokSIGNAL = "signal" const tokSIGNAL = "signal"
func init() {
requirements[tokSIGNAL] = requirement{
"access": {
"r", "w", "rw", "read", "write", "send", "receive",
},
"set": {
"hup", "int", "quit", "ill", "trap", "abrt", "bus", "fpe",
"kill", "usr1", "segv", "usr2", "pipe", "alrm", "term", "stkflt",
"chld", "cont", "stop", "stp", "ttin", "ttou", "urg", "xcpu",
"xfsz", "vtalrm", "prof", "winch", "io", "pwr", "sys", "emt",
"exists", "rtmin+0", "rtmin+1", "rtmin+2", "rtmin+3", "rtmin+4",
"rtmin+5", "rtmin+6", "rtmin+7", "rtmin+8", "rtmin+9", "rtmin+10",
"rtmin+11", "rtmin+12", "rtmin+13", "rtmin+14", "rtmin+15",
"rtmin+16", "rtmin+17", "rtmin+18", "rtmin+19", "rtmin+20",
"rtmin+21", "rtmin+22", "rtmin+23", "rtmin+24", "rtmin+25",
"rtmin+26", "rtmin+27", "rtmin+28", "rtmin+29", "rtmin+30",
"rtmin+31", "rtmin+32",
},
}
}
type Signal struct { type Signal struct {
RuleBase RuleBase
Qualifier Qualifier

View file

@ -73,7 +73,7 @@ var (
"profile", "profile",
"include_if_exists", "include_if_exists",
} }
ruleWeights = make(map[string]int, len(ruleAlphabet)) ruleWeights = generateWeights(ruleAlphabet)
// The order the apparmor file rules should be sorted // The order the apparmor file rules should be sorted
fileAlphabet = []string{ fileAlphabet = []string{
@ -100,9 +100,17 @@ var (
"deny", // 12. Deny rules "deny", // 12. Deny rules
"profile", // 13. Subprofiles "profile", // 13. Subprofiles
} }
fileWeights = make(map[string]int, len(fileAlphabet)) fileWeights = generateWeights(fileAlphabet)
// The order the rule values (access, type, domains, etc) should be sorted
requirements = map[string]requirement{}
requirementsWeights map[string]map[string]map[string]int
) )
func init() {
requirementsWeights = generateRequirementsWeights(requirements)
}
func generateTemplates(names []string) map[string]*template.Template { func generateTemplates(names []string) map[string]*template.Template {
res := make(map[string]*template.Template, len(names)) res := make(map[string]*template.Template, len(names))
base := template.New("").Funcs(tmplFunctionMap) base := template.New("").Funcs(tmplFunctionMap)
@ -132,13 +140,23 @@ func renderTemplate(name string, data any) string {
return res.String() return res.String()
} }
func init() { func generateWeights(alphabet []string) map[string]int {
for i, r := range fileAlphabet { res := make(map[string]int, len(alphabet))
fileWeights[r] = i for i, r := range alphabet {
res[r] = i
} }
for i, r := range ruleAlphabet { return res
ruleWeights[r] = i
} }
func generateRequirementsWeights(requirements map[string]requirement) map[string]map[string]map[string]int {
res := make(map[string]map[string]map[string]int, len(requirements))
for rule, req := range requirements {
res[rule] = make(map[string]map[string]int, len(req))
for key, values := range req {
res[rule][key] = generateWeights(values)
}
}
return res
} }
func join(i any) string { func join(i any) string {

View file

@ -8,6 +8,16 @@ import "slices"
const tokUNIX = "unix" const tokUNIX = "unix"
func init() {
requirements[tokUNIX] = requirement{
"access": []string{
"create", "bind", "listen", "accept", "connect", "shutdown",
"getattr", "setattr", "getopt", "setopt", "send", "receive",
"r", "w", "rw",
},
}
}
type Unix struct { type Unix struct {
RuleBase RuleBase
Qualifier Qualifier