feat(aa): improve rule creation from log.

This commit is contained in:
Alexandre Pujol 2023-09-29 20:07:29 +01:00
parent 13de4182c8
commit c7485326e8
No known key found for this signature in database
GPG Key ID: C5469996F0DF68EC
15 changed files with 62 additions and 57 deletions

View File

@ -9,9 +9,9 @@ type Capability struct {
Name string
}
func CapabilityFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func CapabilityFromLog(log map[string]string) ApparmorRule {
return &Capability{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
Name: log["capname"],
}
}

View File

@ -10,7 +10,7 @@ type ChangeProfile struct {
ProfileName string
}
func ChangeProfileFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func ChangeProfileFromLog(log map[string]string) ApparmorRule {
return &ChangeProfile{
ExecMode: log["mode"],
Exec: log["exec"],

View File

@ -15,9 +15,9 @@ type Dbus struct {
Label string
}
func DbusFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func DbusFromLog(log map[string]string) ApparmorRule {
return &Dbus{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
Access: log["mask"],
Bus: log["bus"],
Name: log["name"],

View File

@ -11,13 +11,9 @@ type File struct {
Target string
}
func FileFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
owner := false
if log["fsuid"] == log["ouid"] && log["OUID"] != "root" {
owner = true
}
func FileFromLog(log map[string]string) ApparmorRule {
return &File{
Qualifier: NewQualifier(owner, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
Path: log["name"],
Access: maskToAccess[log["requested_mask"]],
Target: log["target"],

View File

@ -38,9 +38,9 @@ type Mount struct {
MountPoint string
}
func MountFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func MountFromLog(log map[string]string) ApparmorRule {
return &Mount{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
MountConditions: MountConditions{
Fs: "",
Op: "",
@ -79,9 +79,9 @@ type Umount struct {
MountPoint string
}
func UmountFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func UmountFromLog(log map[string]string) ApparmorRule {
return &Umount{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
MountConditions: MountConditions{
Fs: "",
Op: "",
@ -116,9 +116,9 @@ type Remount struct {
MountPoint string
}
func RemountFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func RemountFromLog(log map[string]string) ApparmorRule {
return &Remount{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
MountConditions: MountConditions{
Fs: "",
Op: "",

View File

@ -11,9 +11,9 @@ type Mqueue struct {
Label string
}
func MqueueFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func MqueueFromLog(log map[string]string) ApparmorRule {
return &Mqueue{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
Access: maskToAccess[log["requested_mask"]],
Type: log["type"],
Label: log["label"],

View File

@ -33,9 +33,9 @@ type Network struct {
AddressExpr
}
func NetworkFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func NetworkFromLog(log map[string]string) ApparmorRule {
return &Network{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
AddressExpr: AddressExpr{
Source: log["laddr"],
Destination: log["faddr"],

View File

@ -11,9 +11,9 @@ type PivotRoot struct {
TargetProfile string
}
func PivotRootFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func PivotRootFromLog(log map[string]string) ApparmorRule {
return &PivotRoot{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
OldRoot: log["oldroot"],
NewRoot: log["root"],
TargetProfile: log["name"],

View File

@ -66,15 +66,7 @@ func (p *AppArmorProfile) String() string {
// AddRule adds a new rule to the profile from a log map
func (p *AppArmorProfile) AddRule(log map[string]string) {
noNewPrivs := false
fileInherit := false
if log["operation"] == "file_inherit" {
fileInherit = true
}
switch log["error"] {
case "-1":
noNewPrivs = true
case "-2":
if !slices.Contains(p.Flags, "mediate_deleted") {
p.Flags = append(p.Flags, "mediate_deleted")
@ -90,36 +82,36 @@ func (p *AppArmorProfile) AddRule(log map[string]string) {
switch log["class"] {
case "cap":
p.Rules = append(p.Rules, CapabilityFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, CapabilityFromLog(log))
case "net":
p.Rules = append(p.Rules, NetworkFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, NetworkFromLog(log))
case "mount":
p.Rules = append(p.Rules, MountFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, MountFromLog(log))
case "remount":
p.Rules = append(p.Rules, RemountFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, RemountFromLog(log))
case "umount":
p.Rules = append(p.Rules, UmountFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, UmountFromLog(log))
case "pivot_root":
p.Rules = append(p.Rules, PivotRootFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, PivotRootFromLog(log))
case "change_profile":
p.Rules = append(p.Rules, RemountFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, RemountFromLog(log))
case "mqueue":
p.Rules = append(p.Rules, MqueueFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, MqueueFromLog(log))
case "signal":
p.Rules = append(p.Rules, SignalFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, SignalFromLog(log))
case "ptrace":
p.Rules = append(p.Rules, PtraceFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, PtraceFromLog(log))
case "namespace":
p.Rules = append(p.Rules, UsernsFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, UsernsFromLog(log))
case "unix":
p.Rules = append(p.Rules, UnixFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, UnixFromLog(log))
case "file":
p.Rules = append(p.Rules, FileFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, FileFromLog(log))
default:
if strings.Contains(log["operation"], "dbus") {
p.Rules = append(p.Rules, DbusFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, DbusFromLog(log))
} else if log["family"] == "unix" {
p.Rules = append(p.Rules, UnixFromLog(log, noNewPrivs, fileInherit))
p.Rules = append(p.Rules, UnixFromLog(log))
}
}
}

View File

@ -10,9 +10,9 @@ type Ptrace struct {
Peer string
}
func PtraceFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func PtraceFromLog(log map[string]string) ApparmorRule {
return &Ptrace{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
Access: maskToAccess[log["requested_mask"]],
Peer: log["peer"],
}

View File

@ -13,7 +13,24 @@ type Qualifier struct {
FileInherit bool
}
func NewQualifier(owner, noNewPrivs, fileInherit bool) Qualifier {
func NewQualifierFromLog(log map[string]string) Qualifier {
owner := false
fsuid, hasFsUID := log["fsuid"]
ouid, hasOuUID := log["ouid"]
OUID, hasOUID := log["OUID"]
isDbus := strings.Contains(log["operation"], "dbus")
if hasFsUID && hasOuUID && hasOUID && fsuid == ouid && OUID != "root" && !isDbus {
owner = true
}
fileInherit := false
if log["operation"] == "file_inherit" {
fileInherit = true
}
noNewPrivs := false
if log["error"] == "-1" {
noNewPrivs = true
}
return Qualifier{
Audit: false,
AccessType: "",

View File

@ -12,7 +12,7 @@ import (
func TestRule_FromLog(t *testing.T) {
tests := []struct {
name string
fromLog func(map[string]string, bool, bool) ApparmorRule
fromLog func(map[string]string) ApparmorRule
log map[string]string
want ApparmorRule
}{
@ -73,7 +73,7 @@ func TestRule_FromLog(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.fromLog(tt.log, false, false); !reflect.DeepEqual(got, tt.want) {
if got := tt.fromLog(tt.log); !reflect.DeepEqual(got, tt.want) {
t.Errorf("RuleFromLog() = %v, want %v", got, tt.want)
}
})

View File

@ -11,9 +11,9 @@ type Signal struct {
Peer string
}
func SignalFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func SignalFromLog(log map[string]string) ApparmorRule {
return &Signal{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
Access: maskToAccess[log["requested_mask"]],
Set: log["signal"],
Peer: log["peer"],

View File

@ -17,9 +17,9 @@ type Unix struct {
PeerAddr string
}
func UnixFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func UnixFromLog(log map[string]string) ApparmorRule {
return &Unix{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
Access: maskToAccess[log["requested_mask"]],
Type: log["sock_type"],
Protocol: log["protocol"],

View File

@ -9,9 +9,9 @@ type Userns struct {
Create bool
}
func UsernsFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRule {
func UsernsFromLog(log map[string]string) ApparmorRule {
return &Userns{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Qualifier: NewQualifierFromLog(log),
Create: true,
}
}