feat(aa-log): add less & equals rule methods.

This commit is contained in:
Alexandre Pujol 2023-09-25 00:09:11 +01:00
parent 923bb66eba
commit e23e10d7b7
Failed to generate hash of commit
17 changed files with 394 additions and 86 deletions

View file

@ -15,3 +15,16 @@ func CapabilityFromLog(log map[string]string, noNewPrivs, fileInherit bool) Appa
Name: log["capname"],
}
}
func (r *Capability) Less(other any) bool {
o, _ := other.(*Capability)
if r.Name == o.Name {
return r.Qualifier.Less(o.Qualifier)
}
return r.Name < o.Name
}
func (r *Capability) Equals(other any) bool {
o, _ := other.(*Capability)
return r.Name == o.Name && r.Qualifier.Equals(o.Qualifier)
}

View file

@ -17,3 +17,19 @@ func ChangeProfileFromLog(log map[string]string, noNewPrivs, fileInherit bool) A
ProfileName: log["name"],
}
}
func (r *ChangeProfile) Less(other any) bool {
o, _ := other.(*ChangeProfile)
if r.ExecMode == o.ExecMode {
if r.Exec == o.Exec {
return r.ProfileName < o.ProfileName
}
return r.Exec < o.Exec
}
return r.ExecMode < o.ExecMode
}
func (r *ChangeProfile) Equals(other any) bool {
o, _ := other.(*ChangeProfile)
return r.ExecMode == o.ExecMode && r.Exec == o.Exec && r.ProfileName == o.ProfileName
}

View file

@ -27,3 +27,36 @@ func DbusFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRu
Label: log["peer_label"],
}
}
func (r *Dbus) Less(other any) bool {
o, _ := other.(*Dbus)
if r.Qualifier.Equals(o.Qualifier) {
if r.Access == o.Access {
if r.Bus == o.Bus {
if r.Name == o.Name {
if r.Path == o.Path {
if r.Interface == o.Interface {
if r.Member == o.Member {
return r.Label < o.Label
}
return r.Member < o.Member
}
return r.Interface < o.Interface
}
return r.Path < o.Path
}
return r.Name < o.Name
}
return r.Bus < o.Bus
}
return r.Access < o.Access
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Dbus) Equals(other any) bool {
o, _ := other.(*Dbus)
return r.Access == o.Access && r.Bus == o.Bus && r.Name == o.Name &&
r.Path == o.Path && r.Interface == o.Interface &&
r.Member == o.Member && r.Label == o.Label && r.Qualifier.Equals(o.Qualifier)
}

View file

@ -23,3 +23,24 @@ func FileFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRu
Target: log["target"],
}
}
func (r *File) Less(other any) bool {
o, _ := other.(*File)
if r.Qualifier.Equals(o.Qualifier) {
if r.Path == o.Path {
if r.Access == o.Access {
return r.Target < o.Target
}
return r.Access < o.Access
}
return r.Path < o.Path
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *File) Equals(other any) bool {
o, _ := other.(*File)
return r.Path == o.Path && r.Access == o.Access &&
r.Target == o.Target && r.Qualifier.Equals(o.Qualifier)
}

View file

@ -10,3 +10,19 @@ type Include struct {
IsMagic bool
}
func (r *Include) Less(other any) bool {
o, _ := other.(*Include)
if r.Path == o.Path {
if r.IsMagic == o.IsMagic {
return r.IfExists
}
return r.IsMagic
}
return r.Path < o.Path
}
func (r *Include) Equals(other any) bool {
o, _ := other.(*Include)
return r.Path == o.Path && r.IsMagic == o.IsMagic &&
r.IfExists == o.IfExists
}

View file

@ -10,3 +10,18 @@ type IOUring struct {
Label string
}
func (r *IOUring) Less(other any) bool {
o, _ := other.(*IOUring)
if r.Qualifier.Equals(o.Qualifier) {
if r.Access == o.Access {
return r.Label < o.Label
}
return r.Access < o.Access
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *IOUring) Equals(other any) bool {
o, _ := other.(*IOUring)
return r.Access == o.Access && r.Label == o.Label && r.Qualifier.Equals(o.Qualifier)
}

View file

@ -13,6 +13,24 @@ type MountConditions struct {
Options []string
}
func (m MountConditions) Less(other MountConditions) bool {
if m.Fs == other.Fs {
if m.Op == other.Op {
if m.FsType == other.FsType {
return len(m.Options) < len(other.Options)
}
return m.FsType < other.FsType
}
return m.Op < other.Op
}
return m.Fs < other.Fs
}
func (m MountConditions) Equals(other MountConditions) bool {
return m.Fs == other.Fs && m.Op == other.Op && m.FsType == other.FsType &&
slices.Equal(m.Options, other.Options)
}
type Mount struct {
Qualifier
MountConditions
@ -33,6 +51,28 @@ func MountFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorR
MountPoint: log["name"],
}
}
func (r *Mount) Less(other any) bool {
o, _ := other.(*Mount)
if r.Qualifier.Equals(o.Qualifier) {
if r.Source == o.Source {
if r.MountPoint == o.MountPoint {
return r.MountConditions.Less(o.MountConditions)
}
return r.MountPoint < o.MountPoint
}
return r.Source < o.Source
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Mount) Equals(other any) bool {
o, _ := other.(*Mount)
return r.Source == o.Source && r.MountPoint == o.MountPoint &&
r.MountConditions.Equals(o.MountConditions) &&
r.Qualifier.Equals(o.Qualifier)
}
type Umount struct {
Qualifier
MountConditions
@ -52,6 +92,24 @@ func UmountFromLog(log map[string]string, noNewPrivs, fileInherit bool) Apparmor
}
}
func (r *Umount) Less(other any) bool {
o, _ := other.(*Umount)
if r.Qualifier.Equals(o.Qualifier) {
if r.MountPoint == o.MountPoint {
return r.MountConditions.Less(o.MountConditions)
}
return r.MountPoint < o.MountPoint
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Umount) Equals(other any) bool {
o, _ := other.(*Umount)
return r.MountPoint == o.MountPoint &&
r.MountConditions.Equals(o.MountConditions) &&
r.Qualifier.Equals(o.Qualifier)
}
type Remount struct {
Qualifier
MountConditions
@ -70,3 +128,21 @@ func RemountFromLog(log map[string]string, noNewPrivs, fileInherit bool) Apparmo
MountPoint: log["name"],
}
}
func (r *Remount) Less(other any) bool {
o, _ := other.(*Remount)
if r.Qualifier.Equals(o.Qualifier) {
if r.MountPoint == o.MountPoint {
return r.MountConditions.Less(o.MountConditions)
}
return r.MountPoint < o.MountPoint
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Remount) Equals(other any) bool {
o, _ := other.(*Remount)
return r.MountPoint == o.MountPoint &&
r.MountConditions.Equals(o.MountConditions) &&
r.Qualifier.Equals(o.Qualifier)
}

View file

@ -19,3 +19,22 @@ func MqueueFromLog(log map[string]string, noNewPrivs, fileInherit bool) Apparmor
Label: log["label"],
}
}
func (r *Mqueue) Less(other any) bool {
o, _ := other.(*Mqueue)
if r.Qualifier.Equals(o.Qualifier) {
if r.Access == o.Access {
if r.Type == o.Type {
return r.Label < o.Label
}
return r.Type < o.Type
}
return r.Access < o.Access
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Mqueue) Equals(other any) bool {
o, _ := other.(*Mqueue)
return r.Access == o.Access && r.Type == o.Type && r.Label == o.Label && r.Qualifier.Equals(o.Qualifier)
}

View file

@ -10,6 +10,20 @@ type AddressExpr struct {
Port string
}
func (r AddressExpr) Equals(other AddressExpr) bool {
return r.Source == other.Source && r.Destination == other.Destination &&
r.Port == other.Port
}
func (r AddressExpr) Less(other AddressExpr) bool {
if r.Source == other.Source {
if r.Destination == other.Destination {
return r.Port < other.Port
}
return r.Destination < other.Destination
}
return r.Source < other.Source
}
type Network struct {
Qualifier
@ -32,3 +46,24 @@ func NetworkFromLog(log map[string]string, noNewPrivs, fileInherit bool) Apparmo
Protocol: log["protocol"],
}
}
func (r *Network) Less(other any) bool {
o, _ := other.(*Network)
if r.Qualifier.Equals(o.Qualifier) {
if r.Domain == o.Domain {
if r.Type == o.Type {
return r.Protocol < o.Protocol
}
return r.Type < o.Type
}
return r.Domain < o.Domain
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Network) Equals(other any) bool {
o, _ := other.(*Network)
return r.Domain == o.Domain && r.Type == o.Type &&
r.Protocol == o.Protocol && r.AddressExpr.Equals(o.AddressExpr) &&
r.Qualifier.Equals(o.Qualifier)
}

View file

@ -19,3 +19,24 @@ func PivotRootFromLog(log map[string]string, noNewPrivs, fileInherit bool) Appar
TargetProfile: log["name"],
}
}
func (r *PivotRoot) Less(other any) bool {
o, _ := other.(*PivotRoot)
if r.Qualifier.Equals(o.Qualifier) {
if r.OldRoot == o.OldRoot {
if r.NewRoot == o.NewRoot {
return r.TargetProfile < o.TargetProfile
}
return r.NewRoot < o.NewRoot
}
return r.OldRoot < o.OldRoot
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *PivotRoot) Equals(other any) bool {
o, _ := other.(*PivotRoot)
return r.OldRoot == o.OldRoot && r.NewRoot == o.NewRoot &&
r.TargetProfile == o.TargetProfile &&
r.Qualifier.Equals(o.Qualifier)
}

View file

@ -18,3 +18,19 @@ func PtraceFromLog(log map[string]string, noNewPrivs, fileInherit bool) Apparmor
}
}
func (r *Ptrace) Less(other any) bool {
o, _ := other.(*Ptrace)
if r.Qualifier.Equals(o.Qualifier) {
if r.Access == o.Access {
return r.Peer == o.Peer
}
return r.Access < o.Access
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Ptrace) Equals(other any) bool {
o, _ := other.(*Ptrace)
return r.Access == o.Access && r.Peer == o.Peer &&
r.Qualifier.Equals(o.Qualifier)
}

View file

@ -9,3 +9,19 @@ type Rlimit struct {
Op string
Value string
}
func (r *Rlimit) Less(other any) bool {
o, _ := other.(*Rlimit)
if r.Key == o.Key {
if r.Op == o.Op {
return r.Value < o.Value
}
return r.Op < o.Op
}
return r.Key < o.Key
}
func (r *Rlimit) Equals(other any) bool {
o, _ := other.(*Rlimit)
return r.Key == o.Key && r.Op == o.Op && r.Value == o.Value
}

View file

@ -23,97 +23,22 @@ func NewQualifier(owner, noNewPrivs, fileInherit bool) Qualifier {
}
}
func NewCapability(log map[string]string, noNewPrivs, fileInherit bool) Capability {
return Capability{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Name: log["capname"],
func (r Qualifier) Less(other Qualifier) bool {
if r.Audit == other.Audit {
if r.AccessType == other.AccessType {
return r.Owner
}
return r.AccessType < other.AccessType
}
return r.Audit
}
func NewNetwork(log map[string]string, noNewPrivs, fileInherit bool) Network {
return Network{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
AddressExpr: AddressExpr{
Source: log["laddr"],
Destination: log["faddr"],
Port: log["lport"],
},
Domain: log["family"],
Type: log["sock_type"],
Protocol: log["protocol"],
}
func (r Qualifier) Equals(other Qualifier) bool {
return r.Audit == other.Audit && r.AccessType == other.AccessType &&
r.Owner == other.Owner && r.NoNewPrivs == other.NoNewPrivs &&
r.FileInherit == other.FileInherit
}
func NewFile(log map[string]string, noNewPrivs, fileInherit bool) File {
owner := false
if log["fsuid"] == log["ouid"] && log["OUID"] != "root" {
owner = true
}
return File{
Qualifier: NewQualifier(owner, noNewPrivs, fileInherit),
Path: log["name"],
Access: maskToAccess[log["requested_mask"]],
Target: log["target"],
}
}
func NewSignal(log map[string]string, noNewPrivs, fileInherit bool) Signal {
return Signal{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Access: maskToAccess[log["requested_mask"]],
Set: log["signal"],
Peer: log["peer"],
}
}
func NewPtrace(log map[string]string, noNewPrivs, fileInherit bool) Ptrace {
return Ptrace{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Access: maskToAccess[log["requested_mask"]],
Peer: log["peer"],
}
}
func NewUnix(log map[string]string, noNewPrivs, fileInherit bool) Unix {
return Unix{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Access: maskToAccess[log["requested_mask"]],
Type: log["sock_type"],
Protocol: log["protocol"],
Address: log["addr"],
Label: log["peer_label"],
Attr: log["attr"],
Opt: log["opt"],
Peer: log["peer"],
PeerAddr: log["peer_addr"],
}
}
func NewMount(log map[string]string, noNewPrivs, fileInherit bool) Mount {
return Mount{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
MountConditions: MountConditions{
Fs: "",
Op: "",
FsType: log["fstype"],
Options: []string{},
},
Source: log["srcname"],
MountPoint: log["name"],
}
}
func NewDbus(log map[string]string, noNewPrivs, fileInherit bool) Dbus {
return Dbus{
Qualifier: NewQualifier(false, noNewPrivs, fileInherit),
Access: log["mask"],
Bus: log["bus"],
Name: log["name"],
Path: log["path"],
Interface: log["interface"],
Member: log["member"],
Label: log["peer_label"],
}
// Preamble specific rules
type Abi struct {

View file

@ -20,3 +20,22 @@ func SignalFromLog(log map[string]string, noNewPrivs, fileInherit bool) Apparmor
}
}
func (r *Signal) Less(other any) bool {
o, _ := other.(*Signal)
if r.Qualifier.Equals(o.Qualifier) {
if r.Access == o.Access {
if r.Set == o.Set {
return r.Peer < o.Peer
}
return r.Set < o.Set
}
return r.Access < o.Access
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Signal) Equals(other any) bool {
o, _ := other.(*Signal)
return r.Access == o.Access && r.Set == o.Set &&
r.Peer == o.Peer && r.Qualifier.Equals(o.Qualifier)
}

View file

@ -31,3 +31,43 @@ func UnixFromLog(log map[string]string, noNewPrivs, fileInherit bool) ApparmorRu
PeerAddr: log["peer_addr"],
}
}
func (r *Unix) Less(other any) bool {
o, _ := other.(*Unix)
if r.Qualifier.Equals(o.Qualifier) {
if r.Access == o.Access {
if r.Type == o.Type {
if r.Protocol == o.Protocol {
if r.Address == o.Address {
if r.Label == o.Label {
if r.Attr == o.Attr {
if r.Opt == o.Opt {
if r.Peer == o.Peer {
return r.PeerAddr < o.PeerAddr
}
return r.Peer < o.Peer
}
return r.Opt < o.Opt
}
return r.Attr < o.Attr
}
return r.Label < o.Label
}
return r.Address < o.Address
}
return r.Protocol < o.Protocol
}
return r.Type < o.Type
}
return r.Access < o.Access
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Unix) Equals(other any) bool {
o, _ := other.(*Unix)
return r.Access == o.Access && r.Type == o.Type &&
r.Protocol == o.Protocol && r.Address == o.Address &&
r.Label == o.Label && r.Attr == o.Attr && r.Opt == o.Opt &&
r.Peer == o.Peer && r.PeerAddr == o.PeerAddr && r.Qualifier.Equals(o.Qualifier)
}

View file

@ -16,3 +16,15 @@ func UsernsFromLog(log map[string]string, noNewPrivs, fileInherit bool) Apparmor
}
}
func (r *Userns) Less(other any) bool {
o, _ := other.(*Userns)
if r.Qualifier.Equals(o.Qualifier) {
return r.Create
}
return r.Qualifier.Less(o.Qualifier)
}
func (r *Userns) Equals(other any) bool {
o, _ := other.(*Userns)
return r.Create == o.Create && r.Qualifier.Equals(o.Qualifier)
}

View file

@ -12,17 +12,32 @@ import (
"strings"
"github.com/arduino/go-paths-helper"
"golang.org/x/exp/slices"
)
var (
regVariablesDef = regexp.MustCompile(`@{(.*)}\s*[+=]+\s*(.*)`)
regVariablesRef = regexp.MustCompile(`@{([^{}]+)}`)
// Default Apparmor magic directory: /etc/apparmor.d/.
MagicRoot = paths.New("/etc/apparmor.d")
)
type Variable struct {
Name string
Values []string
}
func (r Variable) Less(other Variable) bool {
if r.Name == other.Name {
return len(r.Values) < len(other.Values)
}
return r.Name < other.Name
}
func (r Variable) Equals(other Variable) bool {
return r.Name == other.Name && slices.Equal(r.Values, other.Values)
}
// DefaultTunables return a minimal working profile to build the profile
// It should not be used when loading file from /etc/apparmor.d