apparmor.d/pkg/aa/rules_test.go

405 lines
9.4 KiB
Go

// apparmor.d - Full set of apparmor profiles
// Copyright (C) 2021-2024 Alexandre Pujol <alexandre@pujol.io>
// SPDX-License-Identifier: GPL-2.0-only
package aa
import (
"reflect"
"testing"
)
func TestRules_FromLog(t *testing.T) {
for _, tt := range testRule {
if tt.fromLog == nil {
continue
}
t.Run(tt.name, func(t *testing.T) {
if got := tt.fromLog(tt.log); !reflect.DeepEqual(got, tt.rule) {
t.Errorf("RuleFromLog() = %v, want %v", got, tt.rule)
}
})
}
}
func TestRules_Validate(t *testing.T) {
for _, tt := range testRule {
t.Run(tt.name, func(t *testing.T) {
if err := tt.rule.Validate(); (err != nil) != tt.wValidErr {
t.Errorf("Rules.Validate() error = %v, wantErr %v", err, tt.wValidErr)
}
})
}
}
func TestCapability_Compare(t *testing.T) {
for _, tt := range testRule {
t.Run(tt.name, func(t *testing.T) {
if got := tt.rule.Compare(tt.other); got != tt.wCompare {
t.Errorf("Rule.Compare() = %v, want %v", got, tt.wCompare)
}
})
}
}
func TestRules_String(t *testing.T) {
for _, tt := range testRule {
t.Run(tt.name, func(t *testing.T) {
if got := tt.rule.String(); got != tt.wString {
t.Errorf("Rule.String() = %v, want %v", got, tt.wString)
}
})
}
}
var (
// Test cases for the Rule interface
testRule = []struct {
name string
fromLog func(map[string]string) Rule
log map[string]string
rule Rule
wValidErr bool
other Rule
wCompare int
wString string
}{
{
name: "comment",
rule: comment1,
other: comment2,
wCompare: 0,
wString: "#comment",
},
{
name: "abi",
rule: abi1,
other: abi2,
wCompare: 1,
wString: "abi <abi/4.0>,",
},
{
name: "alias",
rule: alias1,
other: alias2,
wCompare: -1,
wString: "alias /mnt/usr -> /usr,",
},
{
name: "include1",
rule: include1,
other: includeLocal1,
wCompare: -11,
wString: "include <abstraction/base>",
},
{
name: "include2",
rule: include1,
other: include2,
wCompare: 1,
wString: "include <abstraction/base>",
},
{
name: "include-local",
rule: includeLocal1,
other: include1,
wCompare: 11,
wString: "include if exists <local/foo>",
},
{
name: "include/abs",
rule: &Include{Path: "/usr/share/apparmor.d/", IsMagic: false},
other: &Include{Path: "/usr/share/apparmor.d/", IsMagic: true},
wCompare: -1,
wString: `include "/usr/share/apparmor.d/"`,
},
{
name: "variable",
rule: variable1,
other: variable2,
wCompare: 0,
wString: "@{bin} = /{,usr/}{,s}bin",
},
{
name: "all",
rule: all1,
other: all2,
wCompare: 0,
wString: "all,",
},
{
name: "rlimit",
rule: rlimit1,
other: rlimit2,
wCompare: 11,
wString: "set rlimit nproc <= 200,",
},
{
name: "rlimit2",
rule: rlimit2,
other: rlimit2,
wCompare: 0,
wString: "set rlimit cpu <= 2,",
},
{
name: "rlimit3",
rule: rlimit3,
other: rlimit1,
wCompare: -1,
wString: "set rlimit nproc < 2,",
},
{
name: "userns",
rule: userns1,
other: userns2,
wCompare: 1,
wString: "userns,",
},
{
name: "capbability",
fromLog: newCapabilityFromLog,
log: capability1Log,
rule: capability1,
other: capability2,
wCompare: -5,
wString: "capability net_admin,",
},
{
name: "capability/multi",
rule: &Capability{Names: []string{"dac_override", "dac_read_search"}},
other: capability2,
wCompare: -15,
wString: "capability dac_override dac_read_search,",
},
{
name: "capability/all",
rule: &Capability{},
other: capability2,
wCompare: -1,
wString: "capability,",
},
{
name: "network",
fromLog: newNetworkFromLog,
log: network1Log,
rule: network1,
wValidErr: true,
other: network2,
wCompare: 5,
wString: "network netlink raw,",
},
{
name: "mount",
fromLog: newMountFromLog,
log: mount1Log,
rule: mount1,
other: mount2,
wCompare: 38,
wString: "mount fstype=overlay overlay -> /var/lib/docker/overlay2/opaque-bug-check1209538631/merged/, # failed perms check",
},
{
name: "remount",
rule: remount1,
other: remount2,
wCompare: -6,
wString: "remount /,",
},
{
name: "umount",
fromLog: newUmountFromLog,
log: umount1Log,
rule: umount1,
other: umount2,
wCompare: -8,
wString: "umount /,",
},
{
name: "pivot_root1",
fromLog: newPivotRootFromLog,
log: pivotroot1Log,
rule: pivotroot1,
other: pivotroot2,
wCompare: 7,
wString: "pivot_root oldroot=@{run}/systemd/mount-rootfs/ @{run}/systemd/mount-rootfs/,",
},
{
name: "pivot_root2",
rule: pivotroot1,
other: pivotroot3,
wCompare: 28,
wString: "pivot_root oldroot=@{run}/systemd/mount-rootfs/ @{run}/systemd/mount-rootfs/,",
},
{
name: "change_profile1",
fromLog: newChangeProfileFromLog,
log: changeprofile1Log,
rule: changeprofile1,
other: changeprofile2,
wCompare: 17,
wString: "change_profile -> systemd-user,",
},
{
name: "change_profile2",
rule: changeprofile2,
other: changeprofile3,
wCompare: -4,
wString: "change_profile -> brwap,",
},
{
name: "mqueue",
rule: mqueue1,
other: mqueue2,
wCompare: -3,
wString: "mqueue r type=posix /,",
},
{
name: "iouring",
rule: iouring1,
other: iouring2,
wCompare: 4,
wString: "io_uring sqpoll label=foo,",
},
{
name: "signal",
fromLog: newSignalFromLog,
log: signal1Log,
rule: signal1,
other: signal2,
wCompare: -10,
wString: "signal receive set=kill peer=firefox//&firejail-default,",
},
{
name: "ptrace/xdg-document-portal",
fromLog: newPtraceFromLog,
log: ptrace1Log,
rule: ptrace1,
other: ptrace1,
wCompare: 0,
wString: "ptrace read peer=nautilus,",
},
{
name: "ptrace/snap-update-ns.firefox",
fromLog: newPtraceFromLog,
log: ptrace2Log,
rule: ptrace2,
other: ptrace1,
wCompare: 2,
wString: "ptrace readby peer=systemd-journald,",
},
{
name: "unix",
fromLog: newUnixFromLog,
log: unix1Log,
rule: unix1,
other: unix1,
wCompare: 0,
wString: "unix (send receive) type=stream protocol=0 addr=none peer=(label=dbus-daemon, addr=@/tmp/dbus-AaKMpxzC4k),",
},
{
name: "dbus",
fromLog: newDbusFromLog,
log: dbus1Log,
rule: dbus1,
other: dbus1,
wCompare: 0,
wString: "dbus receive bus=session path=/org/gtk/vfs/metadata\n interface=org.gtk.vfs.Metadata\n member=Remove\n peer=(name=:1.15, label=tracker-extract),",
},
{
name: "dbus2",
rule: dbus2,
other: dbus3,
wCompare: 9,
wString: "dbus bind bus=session name=org.gnome.evolution.dataserver.Sources5,",
},
{
name: "dbus/bind",
rule: &Dbus{Access: []string{"bind"}, Bus: "session", Name: "org.gnome.*"},
other: dbus2,
wCompare: -33,
wString: `dbus bind bus=session name=org.gnome.*,`,
},
{
name: "dbus/full",
rule: &Dbus{Bus: "accessibility"},
other: dbus1,
wCompare: -1,
wString: `dbus bus=accessibility,`,
},
{
name: "file",
fromLog: newFileFromLog,
log: file1Log,
rule: file1,
other: file2,
wCompare: -14,
wString: "/usr/share/poppler/cMap/Identity-H r,",
},
{
name: "file/empty",
rule: &File{},
other: &File{},
wCompare: 0,
wString: " ,",
},
{
name: "file/equal",
rule: &File{Path: "/usr/share/poppler/cMap/Identity-H"},
other: &File{Path: "/usr/share/poppler/cMap/Identity-H"},
wCompare: 0,
wString: "/usr/share/poppler/cMap/Identity-H ,",
},
{
name: "file/owner",
rule: &File{Path: "/usr/share/poppler/cMap/Identity-H", Owner: true},
other: &File{Path: "/usr/share/poppler/cMap/Identity-H"},
wCompare: 1,
wString: "owner /usr/share/poppler/cMap/Identity-H ,",
},
{
name: "file/access",
rule: &File{Path: "/usr/share/poppler/cMap/Identity-H", Access: []string{"r"}},
other: &File{Path: "/usr/share/poppler/cMap/Identity-H", Access: []string{"w"}},
wCompare: -5,
wString: "/usr/share/poppler/cMap/Identity-H r,",
},
{
name: "file/close",
rule: &File{Path: "/usr/share/poppler/cMap/"},
other: &File{Path: "/usr/share/poppler/cMap/Identity-H"},
wCompare: -10,
wString: "/usr/share/poppler/cMap/ ,",
},
{
name: "link1",
fromLog: newLinkFromLog,
log: link1Log,
rule: link1,
other: link2,
wCompare: -1,
wString: "link /tmp/mkinitcpio.QDWtza/early@{lib}/firmware/i915/dg1_dmc_ver2_02.bin.zst -> /tmp/mkinitcpio.QDWtza/root@{lib}/firmware/i915/dg1_dmc_ver2_02.bin.zst,",
},
{
name: "link2",
fromLog: newFileFromLog,
log: link3Log,
rule: link3,
other: link1,
wCompare: 1,
wString: "owner link @{user_config_dirs}/kiorc -> @{user_config_dirs}/#3954,",
},
{
name: "profile",
rule: profile1,
other: profile2,
wCompare: -4,
wString: "profile sudo {\n}",
},
{
name: "hat",
rule: hat1,
other: hat2,
wCompare: 3,
wString: "hat user {\n}",
},
}
)