From 6cbc076ba473db871bd293e957bbe8c4f7fe85ad Mon Sep 17 00:00:00 2001 From: Alexandre Pujol Date: Mon, 25 Sep 2023 00:28:28 +0100 Subject: [PATCH] test(aa-log): add unit tests for profile printing. --- pkg/aa/profile_test.go | 155 +++++++++++++++++++++++++++++++++++++++-- tests/string.aa | 42 +++++++++++ 2 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 tests/string.aa diff --git a/pkg/aa/profile_test.go b/pkg/aa/profile_test.go index 99f1a065a..1382155ce 100644 --- a/pkg/aa/profile_test.go +++ b/pkg/aa/profile_test.go @@ -1,26 +1,173 @@ // apparmor.d - Full set of apparmor profiles -// Copyright (C) 2023 Alexandre Pujol +// Copyright (C) 2021-2023 Alexandre Pujol // SPDX-License-Identifier: GPL-2.0-only package aa import ( + "reflect" + "strings" "testing" + + "github.com/arduino/go-paths-helper" ) +func readprofile(path string) string { + file := paths.New("../../").Join(path) + lines, err := file.ReadFileAsLines() + if err != nil { + panic(err) + } + res := "" + for _, line := range lines { + if strings.HasPrefix(line, "#") { + continue + } + res += line + "\n" + } + return res[:len(res)-1] +} + func TestAppArmorProfile_String(t *testing.T) { tests := []struct { name string - p AppArmorProfile + p *AppArmorProfile want string }{ { name: "empty", - p: AppArmorProfile{}, - want: `profile { + p: &AppArmorProfile{}, + want: `profile { } `, }, + { + name: "foo", + p: &AppArmorProfile{ + Preamble: Preamble{ + Abi: []Abi{ + { + IsMagic: true, + Path: "abi/4.0", + }, + }, + Includes: []Include{ + { + IfExists: false, + IsMagic: true, + Path: "tunables/global", + }, + }, + Aliases: []Alias{ + { + Path: "/mnt/usr", + RewrittenPath: "/usr", + }, + }, + Variables: []Variable{ + { + Name: "exec_path", + Values: []string{"@{bin}/foo", "@{lib}/foo"}, + }, + }, + }, + Profile: Profile{ + Name: "foo", + Attachments: []string{"@{exec_path}"}, + Attributes: map[string]string{"security.tagged": "allowed"}, + Flags: []string{"complain", "attach_disconnected"}, + Rules: []ApparmorRule{ + &Include{ + IfExists: false, + IsMagic: true, + Path: "abstractions/base", + }, + &Include{ + IfExists: false, + IsMagic: true, + Path: "abstractions/nameservice-strict", + }, + &Rlimit{ + Key: "nproc", + Op: "<=", + Value: "200", + }, + &Capability{Name: "dac_read_search"}, + &Capability{Name: "dac_override"}, + &Network{ + Domain: "inet", + Type: "stream", + }, + &Network{ + Domain: "inet6", + Type: "stream", + }, + &Mount{ + MountConditions: MountConditions{ + FsType: "fuse.portal", + Options: []string{"rw", "rbind"}, + }, + Source: "@{run}/user/@{uid}/ ", + MountPoint: "/", + }, + &Umount{ + MountConditions: MountConditions{}, + MountPoint: "@{run}/user/@{uid}/", + }, + &Signal{ + Access: "receive", + Set: "term", + Peer: "at-spi-bus-launcher", + }, + + &Ptrace{ + Access: "read", + Peer: "nautilus", + }, + &Unix{ + Access: "send receive", + Type: "stream", + Address: "@/tmp/.ICE-unix/1995", + Peer: "gnome-shell", + PeerAddr: "none", + }, + &Dbus{ + Access: "bind", + Bus: "session", + Name: "org.gnome.*", + }, + &Dbus{ + Access: "receive", + Bus: "system", + Name: ":1.3", + Path: "/org/freedesktop/DBus", + Interface: "org.freedesktop.DBus", + Member: "AddMatch", + Label: "power-profiles-daemon", + }, + &File{ + Path: "/opt/intel/oneapi/compiler/*/linux/lib/*.so./*", + Access: "rm", + }, + + &File{ + Path: "@{PROC}/@{pid}/task/@{tid}/comm", + Access: "rw", + }, + &File{ + Path: "@{sys}/devices/pci[0-9]*/**/class", + Access: "r", + }, + &Include{ + IfExists: true, + IsMagic: true, + Path: "local/foo", + }, + }, + }, + }, + want: readprofile("tests/string.aa"), + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/tests/string.aa b/tests/string.aa new file mode 100644 index 000000000..64ef386ac --- /dev/null +++ b/tests/string.aa @@ -0,0 +1,42 @@ +# Simple test profile for the AppArmorProfile.String() method +abi , + +alias /mnt/usr -> /usr, + +include , + +@{exec_path} = @{bin}/foo @{lib}/foo +profile foo @{exec_path} xattrs=(security.tagged=allowed) flags=(complain attach_disconnected) { + include + include + + set rlimit nproc <= 200, + + capability dac_read_search, + capability dac_override, + + network inet stream, + network inet6 stream, + + mount fstype=fuse.portal options=(rw rbind) @{run}/user/@{uid}/ -> /, + + umount @{run}/user/@{uid}/, + + signal (receive) set=(term) peer=at-spi-bus-launcher, + + ptrace (read) peer=nautilus, + + unix (send receive) type=stream addr=@/tmp/.ICE-unix/1995 peer=(label=gnome-shell, addr=none), + + dbus bind bus=session name=org.gnome.*, + dbus receive bus=system path=/org/freedesktop/DBus + interface=org.freedesktop.DBus + member=AddMatch + peer=(name=:1.3, label=power-profiles-daemon), + + /opt/intel/oneapi/compiler/*/linux/lib/*.so./* rm, + @{PROC}/@{pid}/task/@{tid}/comm rw, + @{sys}/devices/pci[0-9]*/**/class r, + + include if exists +}