mirror of
https://github.com/roddhjav/apparmor.d.git
synced 2025-02-22 09:55:36 +01:00
feat(aa-log): improve error formating on rules.
This commit is contained in:
parent
04cae35e6e
commit
46d25ed922
6 changed files with 45 additions and 13 deletions
|
@ -62,7 +62,7 @@ var (
|
||||||
"apparmor": "ALLOWED",
|
"apparmor": "ALLOWED",
|
||||||
"class": "mount",
|
"class": "mount",
|
||||||
"operation": "mount",
|
"operation": "mount",
|
||||||
"info": "failed perms check", // TODO: not attach_disconnected
|
"info": "failed perms check",
|
||||||
"error": "-13",
|
"error": "-13",
|
||||||
"profile": "dockerd",
|
"profile": "dockerd",
|
||||||
"name": "/var/lib/docker/overlay2/metacopy-check906831159/merged/",
|
"name": "/var/lib/docker/overlay2/metacopy-check906831159/merged/",
|
||||||
|
@ -71,11 +71,13 @@ var (
|
||||||
"srcname": "overlay",
|
"srcname": "overlay",
|
||||||
}
|
}
|
||||||
mount1 = &Mount{
|
mount1 = &Mount{
|
||||||
|
Qualifier: Qualifier{Comment: "failed perms check"},
|
||||||
MountConditions: MountConditions{FsType: "overlay", Options: []string{}},
|
MountConditions: MountConditions{FsType: "overlay", Options: []string{}},
|
||||||
Source: "overlay",
|
Source: "overlay",
|
||||||
MountPoint: "/var/lib/docker/overlay2/opaque-bug-check1209538631/merged/",
|
MountPoint: "/var/lib/docker/overlay2/opaque-bug-check1209538631/merged/",
|
||||||
}
|
}
|
||||||
mount2 = &Mount{
|
mount2 = &Mount{
|
||||||
|
Qualifier: Qualifier{Comment: "failed perms check"},
|
||||||
MountConditions: MountConditions{FsType: "overlay", Options: []string{}},
|
MountConditions: MountConditions{FsType: "overlay", Options: []string{}},
|
||||||
Source: "overlay",
|
Source: "overlay",
|
||||||
MountPoint: "/var/lib/docker/overlay2/metacopy-check906831159/merged/",
|
MountPoint: "/var/lib/docker/overlay2/metacopy-check906831159/merged/",
|
||||||
|
|
|
@ -66,15 +66,16 @@ func (p *AppArmorProfile) String() string {
|
||||||
|
|
||||||
// AddRule adds a new rule to the profile from a log map
|
// AddRule adds a new rule to the profile from a log map
|
||||||
func (p *AppArmorProfile) AddRule(log map[string]string) {
|
func (p *AppArmorProfile) AddRule(log map[string]string) {
|
||||||
|
// Generate profile flags and extra rules
|
||||||
switch log["error"] {
|
switch log["error"] {
|
||||||
case "-2":
|
case "-2":
|
||||||
if !slices.Contains(p.Flags, "mediate_deleted") {
|
if !slices.Contains(p.Flags, "mediate_deleted") {
|
||||||
p.Flags = append(p.Flags, "mediate_deleted")
|
p.Flags = append(p.Flags, "mediate_deleted")
|
||||||
}
|
}
|
||||||
case "-13":
|
case "-13":
|
||||||
// FIXME: -13 can be a lot of things, not only attach_disconnected
|
if strings.Contains(log["info"], "namespace creation restricted") {
|
||||||
// Eg: info="User namespace creation restricted"
|
p.Rules = append(p.Rules, UsernsFromLog(log))
|
||||||
if !slices.Contains(p.Flags, "attach_disconnected") {
|
} else if strings.Contains(log["info"], "disconnected path") && !slices.Contains(p.Flags, "attach_disconnected") {
|
||||||
p.Flags = append(p.Flags, "attach_disconnected")
|
p.Flags = append(p.Flags, "attach_disconnected")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -153,7 +153,6 @@ func TestAppArmorProfile_AddRule(t *testing.T) {
|
||||||
log: mount2Log,
|
log: mount2Log,
|
||||||
want: &AppArmorProfile{
|
want: &AppArmorProfile{
|
||||||
Profile: Profile{
|
Profile: Profile{
|
||||||
Flags: []string{"attach_disconnected"},
|
|
||||||
Rules: []ApparmorRule{mount2},
|
Rules: []ApparmorRule{mount2},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
package aa
|
package aa
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
type Rule struct {
|
type Rule struct {
|
||||||
Comment string
|
Comment string
|
||||||
|
@ -12,7 +14,6 @@ type Rule struct {
|
||||||
FileInherit bool
|
FileInherit bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (r *Rule) Less(other any) bool {
|
func (r *Rule) Less(other any) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -28,6 +29,8 @@ type Qualifier struct {
|
||||||
Owner bool
|
Owner bool
|
||||||
NoNewPrivs bool
|
NoNewPrivs bool
|
||||||
FileInherit bool
|
FileInherit bool
|
||||||
|
Optional bool
|
||||||
|
Comment string
|
||||||
Prefix string
|
Prefix string
|
||||||
Padding string
|
Padding string
|
||||||
}
|
}
|
||||||
|
@ -46,20 +49,41 @@ func NewQualifierFromLog(log map[string]string) Qualifier {
|
||||||
if log["apparmor"] == "AUDIT" {
|
if log["apparmor"] == "AUDIT" {
|
||||||
audit = true
|
audit = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fileInherit := false
|
fileInherit := false
|
||||||
if log["operation"] == "file_inherit" {
|
if log["operation"] == "file_inherit" {
|
||||||
fileInherit = true
|
fileInherit = true
|
||||||
}
|
}
|
||||||
|
|
||||||
noNewPrivs := false
|
noNewPrivs := false
|
||||||
if log["error"] == "-1" {
|
optional := false
|
||||||
|
msg := ""
|
||||||
|
switch log["error"] {
|
||||||
|
case "-1":
|
||||||
|
if strings.Contains(log["info"], "optional:") {
|
||||||
|
optional = true
|
||||||
|
msg = strings.Replace(log["info"], "optional: ", "", 1)
|
||||||
|
} else {
|
||||||
noNewPrivs = true
|
noNewPrivs = true
|
||||||
}
|
}
|
||||||
|
case "-13":
|
||||||
|
ignoreProfileInfo := []string{"namespace", "disconnected path"}
|
||||||
|
for _, info := range ignoreProfileInfo {
|
||||||
|
if strings.Contains(log["info"], info) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg = log["info"]
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
return Qualifier{
|
return Qualifier{
|
||||||
Audit: audit,
|
Audit: audit,
|
||||||
AccessType: "",
|
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
NoNewPrivs: noNewPrivs,
|
NoNewPrivs: noNewPrivs,
|
||||||
FileInherit: fileInherit,
|
FileInherit: fileInherit,
|
||||||
|
Optional: optional,
|
||||||
|
Comment: msg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,12 +30,12 @@ var (
|
||||||
tmplAppArmorProfile = generateTemplate()
|
tmplAppArmorProfile = generateTemplate()
|
||||||
|
|
||||||
// convert apparmor requested mask to apparmor access mode
|
// convert apparmor requested mask to apparmor access mode
|
||||||
// TODO: Should be a map of slice, not exhausive yet
|
// TODO: Should be a map of slice, not exhaustive yet
|
||||||
maskToAccess = map[string]string{
|
maskToAccess = map[string]string{
|
||||||
"a": "w",
|
"a": "w",
|
||||||
"c": "w",
|
"c": "w",
|
||||||
"d": "w",
|
"d": "w",
|
||||||
"k": "rk",
|
"k": "k",
|
||||||
"l": "l",
|
"l": "l",
|
||||||
"m": "rm",
|
"m": "rm",
|
||||||
"r": "r",
|
"r": "r",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{{- define "comment" -}}
|
{{- define "comment" -}}
|
||||||
{{- if or .FileInherit .NoNewPrivs -}}
|
{{- if or .FileInherit .NoNewPrivs .Optional .Comment -}}
|
||||||
{{- " #" -}}
|
{{- " #" -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- if .FileInherit -}}
|
{{- if .FileInherit -}}
|
||||||
|
@ -8,4 +8,10 @@
|
||||||
{{- if .NoNewPrivs -}}
|
{{- if .NoNewPrivs -}}
|
||||||
{{- " no new privs" -}}
|
{{- " no new privs" -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
{{- if .Optional -}}
|
||||||
|
{{- " optional:" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- with .Comment -}}
|
||||||
|
{{ " " }}{{ . }}
|
||||||
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
Loading…
Add table
Reference in a new issue