null pointer dereference regression in 5.7
by bauen1
Hi,
After upgrading from linux 5.6 to 5.7 on my debian machines with selinux I've started seeing this null pointer dereference in the audit system. I've included shortened logs for 5.6 without the error and from 5.7 with the error from my laptop. I've also seen it happen in a VM and a server, but don't have the logs anymore. Grift was able to reproduced (presumably) the same issue on fedora with 5.8-rc4.
Steps to reproduce:
Write an selinux policy with a domain for systemd-user-runtime-dir and audit all permissions of the dir class. E.g. `(auditallow systemd_user_runtime_dir_t all_types (dir (all)))`
Switch to permissive mode.
Create a new user and login, log out and wait a few seconds for systemd to stop user-runtime-dir@<uid>.service
I believe this issue was made visible by 1320a4052ea11eb2879eb7361da15a106a780972.
Now a AUDIT_PATH event is also generated by default and systemd-user-runtime-dir is making syscalls that audit_log_name can't handle.
I hope this is enough info to find the root cause.
- bauen1
Log without crash (5.6):
Jul 18 14:26:36 jh-mba kernel: Linux version 5.6.0-2-amd64 (debian-kernel(a)lists.debian.org) (gcc version 9.3.0 (Debian 9.3.0-13)) #1 SMP Debian 5.6.14-2 (2020-06-09)
Jul 18 14:27:53 jh-mba audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=user@1001 comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
Jul 18 14:27:53 jh-mba systemd[1]: Stopping User Runtime Directory /run/user/1001...
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { read } for pid=3178 comm="systemd-user-ru" name="dconf" dev="tmpfs" ino=41325 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { open } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/dconf" dev="tmpfs" ino=41325 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { getattr } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/dconf" dev="tmpfs" ino=41325 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { search } for pid=3178 comm="systemd-user-ru" name="dconf" dev="tmpfs" ino=41325 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { write } for pid=3178 comm="systemd-user-ru" name="dconf" dev="tmpfs" ino=41325 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { remove_name } for pid=3178 comm="systemd-user-ru" name="user" dev="tmpfs" ino=41326 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { unlink } for pid=3178 comm="systemd-user-ru" name="user" dev="tmpfs" ino=41326 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=file permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { rmdir } for pid=3178 comm="systemd-user-ru" name="dconf" dev="tmpfs" ino=41325 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { read } for pid=3178 comm="systemd-user-ru" name="gvfs" dev="tmpfs" ino=42315 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:user_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { open } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/gvfs" dev="tmpfs" ino=42315 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:user_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { getattr } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/gvfs" dev="tmpfs" ino=42315 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:user_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { rmdir } for pid=3178 comm="systemd-user-ru" name="gvfs" dev="tmpfs" ino=42315 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:user_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { read } for pid=3178 comm="systemd-user-ru" name="dbus-1" dev="tmpfs" ino=39557 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:session_dbusd_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { open } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/dbus-1" dev="tmpfs" ino=39557 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:session_dbusd_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { getattr } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/dbus-1" dev="tmpfs" ino=39557 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:session_dbusd_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { search } for pid=3178 comm="systemd-user-ru" name="dbus-1" dev="tmpfs" ino=39557 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:session_dbusd_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { write } for pid=3178 comm="systemd-user-ru" name="dbus-1" dev="tmpfs" ino=39557 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:session_dbusd_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { remove_name } for pid=3178 comm="systemd-user-ru" name="services" dev="tmpfs" ino=39558 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:session_dbusd_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { rmdir } for pid=3178 comm="systemd-user-ru" name="services" dev="tmpfs" ino=39558 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:session_dbusd_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { open } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/pulse" dev="tmpfs" ino=41258 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:pulseaudio_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { getattr } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/pulse" dev="tmpfs" ino=41258 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:pulseaudio_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { search } for pid=3178 comm="systemd-user-ru" name="pulse" dev="tmpfs" ino=41258 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:pulseaudio_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { write } for pid=3178 comm="systemd-user-ru" name="pulse" dev="tmpfs" ino=41258 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:pulseaudio_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { remove_name } for pid=3178 comm="systemd-user-ru" name="native" dev="tmpfs" ino=41259 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:pulseaudio_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { unlink } for pid=3178 comm="systemd-user-ru" name="native" dev="tmpfs" ino=41259 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:pulseaudio_tmp_t:s0 tclass=sock_file permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { rmdir } for pid=3178 comm="systemd-user-ru" name="pulse" dev="tmpfs" ino=41258 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:pulseaudio_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { unlink } for pid=3178 comm="systemd-user-ru" name="bus" dev="tmpfs" ino=41239 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:session_dbusd_runtime_t:s0 tclass=sock_file permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { read } for pid=3178 comm="systemd-user-ru" name="gnupg" dev="tmpfs" ino=42225 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:dirmngr_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { open } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/gnupg" dev="tmpfs" ino=42225 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:dirmngr_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { getattr } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/gnupg" dev="tmpfs" ino=42225 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:dirmngr_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { search } for pid=3178 comm="systemd-user-ru" name="gnupg" dev="tmpfs" ino=42225 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:dirmngr_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { write } for pid=3178 comm="systemd-user-ru" name="gnupg" dev="tmpfs" ino=42225 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:dirmngr_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { remove_name } for pid=3178 comm="systemd-user-ru" name="S.gpg-agent" dev="tmpfs" ino=41252 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:dirmngr_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { unlink } for pid=3178 comm="systemd-user-ru" name="S.gpg-agent" dev="tmpfs" ino=41252 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:dirmngr_tmp_t:s0 tclass=sock_file permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { rmdir } for pid=3178 comm="systemd-user-ru" name="gnupg" dev="tmpfs" ino=42225 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:dirmngr_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { open } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/systemd" dev="tmpfs" ino=39472 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:systemd_user_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { getattr } for pid=3178 comm="systemd-user-ru" path="/run/user/1001/systemd" dev="tmpfs" ino=39472 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:systemd_user_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { search } for pid=3178 comm="systemd-user-ru" name="systemd" dev="tmpfs" ino=39472 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:systemd_user_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { write } for pid=3178 comm="systemd-user-ru" name="systemd" dev="tmpfs" ino=39472 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:systemd_user_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { remove_name } for pid=3178 comm="systemd-user-ru" name="private" dev="tmpfs" ino=41230 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:systemd_user_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { unlink } for pid=3178 comm="systemd-user-ru" name="private" dev="tmpfs" ino=41230 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:systemd_user_runtime_t:s0 tclass=sock_file permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { unlink } for pid=3178 comm="systemd-user-ru" name="notify" dev="tmpfs" ino=41226 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:systemd_user_runtime_notify_t:s0 tclass=sock_file permissive=1
Jul 18 14:27:53 jh-mba audit[3178]: AVC avc: denied { rmdir } for pid=3178 comm="systemd-user-ru" name="units" dev="tmpfs" ino=39473 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:systemd_user_runtime_t:s0 tclass=dir permissive=1
Jul 18 14:27:53 jh-mba systemd[2501]: run-user-1001.mount: Succeeded.
Jul 18 14:27:53 jh-mba systemd[1]: run-user-1001.mount: Succeeded.
Jul 18 14:27:53 jh-mba systemd[2839]: run-user-1001.mount: Succeeded.
Jul 18 14:27:53 jh-mba systemd[1]: user-runtime-dir(a)1001.service: Succeeded.
Jul 18 14:27:53 jh-mba systemd[1]: Stopped User Runtime Directory /run/user/1001.
Log with crash (5.7):
Jul 18 14:30:09 jh-mba kernel: Linux version 5.7.0-1-amd64 (debian-kernel(a)lists.debian.org) (gcc version 9.3.0 (Debian 9.3.0-14), GNU ld (GNU Binutils for Debian) 2.34) #1 SMP Debian 5.7.6-1 (2020-06-24)
Jul 18 14:35:10 jh-mba audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=user@1001 comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
Jul 18 14:35:10 jh-mba systemd[1]: Stopping User Runtime Directory /run/user/1001...
Jul 18 14:35:10 jh-mba audit[3163]: AVC avc: denied { read } for pid=3163 comm="systemd-user-ru" name="dconf" dev="tmpfs" ino=39541 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:35:10 jh-mba audit[3163]: AVC avc: denied { open } for pid=3163 comm="systemd-user-ru" path="/run/user/1001/dconf" dev="tmpfs" ino=39541 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:35:10 jh-mba audit[3163]: SYSCALL arch=c000003e syscall=257 success=yes exit=4 a0=3 a1=55edb4e41073 a2=f0800 a3=0 items=0 ppid=1 pid=3163 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="systemd-user-ru" exe="/usr/lib/systemd/systemd-user-runtime-dir" subj=system_u:system_r:systemd_user_runtime_dir_t:s0 key=(null)
Jul 18 14:35:10 jh-mba audit: PROCTITLE proctitle=2F6C69622F73797374656D642F73797374656D642D757365722D72756E74696D652D6469720073746F700031303031
Jul 18 14:35:10 jh-mba audit[3163]: AVC avc: denied { getattr } for pid=3163 comm="systemd-user-ru" path="/run/user/1001/dconf" dev="tmpfs" ino=39541 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:35:10 jh-mba audit[3163]: SYSCALL arch=c000003e syscall=5 success=yes exit=0 a0=4 a1=7fff95e523b0 a2=7fff95e523b0 a3=7fff95e52414 items=0 ppid=1 pid=3163 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="systemd-user-ru" exe="/usr/lib/systemd/systemd-user-runtime-dir" subj=system_u:system_r:systemd_user_runtime_dir_t:s0 key=(null)
Jul 18 14:35:10 jh-mba audit: PROCTITLE proctitle=2F6C69622F73797374656D642F73797374656D642D757365722D72756E74696D652D6469720073746F700031303031
Jul 18 14:35:10 jh-mba audit[3163]: AVC avc: denied { search } for pid=3163 comm="systemd-user-ru" name="dconf" dev="tmpfs" ino=39541 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:35:10 jh-mba audit[3163]: AVC avc: denied { write } for pid=3163 comm="systemd-user-ru" name="dconf" dev="tmpfs" ino=39541 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:35:10 jh-mba audit[3163]: AVC avc: denied { remove_name } for pid=3163 comm="systemd-user-ru" name="user" dev="tmpfs" ino=39542 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=dir permissive=1
Jul 18 14:35:10 jh-mba audit[3163]: AVC avc: denied { unlink } for pid=3163 comm="systemd-user-ru" name="user" dev="tmpfs" ino=39542 scontext=system_u:system_r:systemd_user_runtime_dir_t:s0 tcontext=user_u:object_r:gconf_tmp_t:s0 tclass=file permissive=1
Jul 18 14:35:10 jh-mba audit[3163]: SYSCALL arch=c000003e syscall=263 success=yes exit=0 a0=4 a1=55edb4e490b3 a2=0 a3=4 items=2 ppid=1 pid=3163 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="systemd-user-ru" exe="/usr/lib/systemd/systemd-user-runtime-dir" subj=system_u:system_r:systemd_user_runtime_dir_t:s0 key=(null)
Jul 18 14:35:10 jh-mba kernel: BUG: kernel NULL pointer dereference, address: 0000000000000060
Jul 18 14:35:10 jh-mba kernel: #PF: supervisor read access in kernel mode
Jul 18 14:35:10 jh-mba kernel: #PF: error_code(0x0000) - not-present page
Jul 18 14:35:11 jh-mba kernel: PGD 0 P4D 0
Jul 18 14:35:11 jh-mba kernel: Oops: 0000 [#1] SMP PTI
Jul 18 14:35:11 jh-mba kernel: CPU: 1 PID: 3163 Comm: systemd-user-ru Tainted: P OE 5.7.0-1-amd64 #1 Debian 5.7.6-1
Jul 18 14:35:11 jh-mba kernel: Hardware name: Apple Inc. MacBookAir6,2/Mac-7DF21CB3ED6977E5, BIOS 110.0.0.0.0 09/17/2018
Jul 18 14:35:11 jh-mba kernel: RIP: 0010:d_path+0x35/0x140
Jul 18 14:35:11 jh-mba kernel: Code: 49 89 fc 48 83 ec 28 48 8b 7f 08 89 54 24 04 65 48 8b 04 25 28 00 00 00 48 89 44 24 20 31 c0 48 63 c2 48 01 f0 48 89 44 24 08 <48> 8b 47 60 48 85 c0 74 22 48 8b 40 48 48 85 c0 74 19 48 3b 7f 18
Jul 18 14:35:11 jh-mba kernel: RSP: 0018:ffffb71e411cfe18 EFLAGS: 00010282
Jul 18 14:35:11 jh-mba kernel: RAX: ffff9a525f18700b RBX: ffff9a524fc52060 RCX: 00000000000004dd
Jul 18 14:35:11 jh-mba kernel: RDX: 000000000000100b RSI: ffff9a525f186000 RDI: 0000000000000000
Jul 18 14:35:11 jh-mba kernel: RBP: ffffb71e411cfe48 R08: ffff9a52672b0060 R09: 0000000000000006
Jul 18 14:35:11 jh-mba kernel: R10: ffff9a522c99e6c0 R11: ffff9a532c99e030 R12: ffff9a524fc522b0
Jul 18 14:35:11 jh-mba kernel: R13: ffff9a52658d3708 R14: ffff9a524fc52000 R15: 0000000000000000
Jul 18 14:35:11 jh-mba kernel: FS: 00007ff68934e980(0000) GS:ffff9a5267280000(0000) knlGS:0000000000000000
Jul 18 14:35:11 jh-mba kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Jul 18 14:35:11 jh-mba kernel: CR2: 0000000000000060 CR3: 0000000226ce6002 CR4: 00000000001606e0
Jul 18 14:35:11 jh-mba kernel: Call Trace:
Jul 18 14:35:11 jh-mba kernel: audit_log_d_path+0x75/0xd0
Jul 18 14:35:11 jh-mba kernel: audit_log_exit+0x63d/0xcf0
Jul 18 14:35:11 jh-mba kernel: ? audit_filter_inodes+0x2e/0x100
Jul 18 14:35:11 jh-mba kernel: __audit_syscall_exit+0x23b/0x2a0
Jul 18 14:35:11 jh-mba kernel: syscall_slow_exit_work+0x117/0x140
Jul 18 14:35:11 jh-mba kernel: do_syscall_64+0x10e/0x180
Jul 18 14:35:11 jh-mba kernel: entry_SYSCALL_64_after_hwframe+0x44/0xa9
Jul 18 14:35:11 jh-mba kernel: RIP: 0033:0x7ff689f8eb67
Jul 18 14:35:11 jh-mba kernel: Code: 73 01 c3 48 8b 0d 29 d3 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 07 01 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d f9 d2 0c 00 f7 d8 64 89 01 48
Jul 18 14:35:11 jh-mba kernel: RSP: 002b:00007fff95e52468 EFLAGS: 00000246 ORIG_RAX: 0000000000000107
Jul 18 14:35:11 jh-mba kernel: RAX: 0000000000000000 RBX: 00007ff68934e830 RCX: 00007ff689f8eb67
Jul 18 14:35:11 jh-mba kernel: RDX: 0000000000000000 RSI: 000055edb4e490b3 RDI: 0000000000000004
Jul 18 14:35:11 jh-mba kernel: RBP: 0000000000000004 R08: 000055edb4e490a0 R09: 00007ff68a05cbe0
Jul 18 14:35:11 jh-mba kernel: R10: 0000000000000004 R11: 0000000000000246 R12: 000055edb4e49040
Jul 18 14:35:11 jh-mba kernel: R13: 0000000000000000 R14: 000055edb4e490a0 R15: 000055edb4e490b3
Jul 18 14:35:11 jh-mba kernel: Modules linked in: rfcomm bnep xt_CHECKSUM cpufreq_powersave xt_MASQUERADE cpufreq_conservative cpufreq_userspace xt_tcpudp nft_compat bridge stp llc overlay fuse nft_chain_nat nf_nat nf_log_ipv6 nf_log_ipv4 nf_log_common nft_log veth intel_rapl_msr btusb btrtl btbcm joydev binfmt_misc btintel nls_ascii nls_cp437 vfat fat bluetooth nft_counter drbg intel_rapl_common asix ansi_cprng ecdh_generic usbnet ecc mii vrf libphy x86_pkg_temp_thermal intel_powerclamp applesmc snd_hda_codec_hdmi snd_hda_codec_cirrus snd_hda_codec_generic coretemp ledtrig_audio evdev wireguard kvm_intel curve25519_x86_64 libcurve25519_generic libchacha20poly1305 snd_hda_intel kvm bcm5974 wl(POE) snd_intel_dspcfg chacha_x86_64 poly1305_x86_64 ip6_udp_tunnel efi_pstore udp_tunnel irqbypass snd_hda_codec libblake2s cfg80211 intel_cstate snd_hda_core blake2s_x86_64 libblake2s_generic libchacha snd_hwdep intel_uncore iTCO_wdt i915 iTCO_vendor_support intel_rapl_perf snd_pcm nft_ct sg efivars pcspkr nf_conntrack
Jul 18 14:35:11 jh-mba kernel: watchdog rfkill snd_timer nf_defrag_ipv6 nf_defrag_ipv4 drm_kms_helper mei_me snd mei cec soundcore i2c_algo_bit sbs sbshc acpi_als kfifo_buf industrialio apple_bl ac button bonding nf_tables parport_pc(E) nfnetlink ppdev(E) lp(E) drm parport(E) sunrpc efivarfs ip_tables x_tables autofs4 ext4 crc16 mbcache jbd2 btrfs blake2b_generic zstd_decompress zstd_compress hid_apple hid_generic usbhid hid dm_crypt dm_mod raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c crc32c_generic raid1 raid0 multipath linear md_mod uas usb_storage sd_mod t10_pi crc_t10dif crct10dif_generic crct10dif_pclmul crct10dif_common crc32_pclmul crc32c_intel ghash_clmulni_intel ahci libahci xhci_pci aesni_intel xhci_hcd libaes crypto_simd libata cryptd glue_helper usbcore scsi_mod i2c_i801 thunderbolt lpc_ich mfd_core usb_common spi_pxa2xx_platform dw_dmac video dw_dmac_core
Jul 18 14:35:11 jh-mba kernel: CR2: 0000000000000060
Jul 18 14:35:11 jh-mba kernel: ---[ end trace 01b46d19ab2d30bf ]---
Jul 18 14:35:11 jh-mba kernel: RIP: 0010:d_path+0x35/0x140
Jul 18 14:35:11 jh-mba kernel: Code: 49 89 fc 48 83 ec 28 48 8b 7f 08 89 54 24 04 65 48 8b 04 25 28 00 00 00 48 89 44 24 20 31 c0 48 63 c2 48 01 f0 48 89 44 24 08 <48> 8b 47 60 48 85 c0 74 22 48 8b 40 48 48 85 c0 74 19 48 3b 7f 18
Jul 18 14:35:11 jh-mba kernel: RSP: 0018:ffffb71e411cfe18 EFLAGS: 00010282
Jul 18 14:35:11 jh-mba kernel: RAX: ffff9a525f18700b RBX: ffff9a524fc52060 RCX: 00000000000004dd
Jul 18 14:35:11 jh-mba kernel: RDX: 000000000000100b RSI: ffff9a525f186000 RDI: 0000000000000000
Jul 18 14:35:11 jh-mba kernel: RBP: ffffb71e411cfe48 R08: ffff9a52672b0060 R09: 0000000000000006
Jul 18 14:35:11 jh-mba kernel: R10: ffff9a522c99e6c0 R11: ffff9a532c99e030 R12: ffff9a524fc522b0
Jul 18 14:35:11 jh-mba kernel: R13: ffff9a52658d3708 R14: ffff9a524fc52000 R15: 0000000000000000
Jul 18 14:35:11 jh-mba kernel: FS: 00007ff68934e980(0000) GS:ffff9a5267280000(0000) knlGS:0000000000000000
Jul 18 14:35:11 jh-mba kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Jul 18 14:35:11 jh-mba kernel: CR2: 0000000000000060 CR3: 0000000226ce6002 CR4: 00000000001606e0
Jul 18 14:35:11 jh-mba kernel: BUG: kernel NULL pointer dereference, address: 0000000000000060
Jul 18 14:35:11 jh-mba kernel: #PF: supervisor read access in kernel mode
Jul 18 14:35:12 jh-mba kernel: #PF: error_code(0x0000) - not-present page
Jul 18 14:35:13 jh-mba kernel: PGD 0 P4D 0
Jul 18 14:35:13 jh-mba kernel: Oops: 0000 [#2] SMP PTI
Jul 18 14:35:13 jh-mba kernel: CPU: 1 PID: 3163 Comm: systemd-user-ru Tainted: P D OE 5.7.0-1-amd64 #1 Debian 5.7.6-1
Jul 18 14:35:13 jh-mba kernel: Hardware name: Apple Inc. MacBookAir6,2/Mac-7DF21CB3ED6977E5, BIOS 110.0.0.0.0 09/17/2018
Jul 18 14:35:13 jh-mba kernel: RIP: 0010:d_path+0x35/0x140
Jul 18 14:35:13 jh-mba kernel: Code: 49 89 fc 48 83 ec 28 48 8b 7f 08 89 54 24 04 65 48 8b 04 25 28 00 00 00 48 89 44 24 20 31 c0 48 63 c2 48 01 f0 48 89 44 24 08 <48> 8b 47 60 48 85 c0 74 22 48 8b 40 48 48 85 c0 74 19 48 3b 7f 18
Jul 18 14:35:13 jh-mba kernel: RSP: 0018:ffffb71e411cfde0 EFLAGS: 00010282
Jul 18 14:35:13 jh-mba kernel: RAX: ffff9a525f18500b RBX: ffff9a524fc52060 RCX: 00000000000004e0
Jul 18 14:35:13 jh-mba kernel: RDX: 000000000000100b RSI: ffff9a525f184000 RDI: 0000000000000000
Jul 18 14:35:13 jh-mba kernel: RBP: ffffb71e411cfe10 R08: ffff9a52672b0060 R09: 0000000000000006
Jul 18 14:35:13 jh-mba kernel: R10: ffff9a522c99cec0 R11: ffff9a532c99c830 R12: ffff9a524fc522b0
Jul 18 14:35:13 jh-mba kernel: R13: ffff9a52658d35e8 R14: ffff9a524fc52000 R15: 0000000000000000
Jul 18 14:35:13 jh-mba kernel: FS: 00007ff68934e980(0000) GS:ffff9a5267280000(0000) knlGS:0000000000000000
Jul 18 14:35:13 jh-mba kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Jul 18 14:35:13 jh-mba kernel: CR2: 0000000000000060 CR3: 0000000226ce6002 CR4: 00000000001606e0
Jul 18 14:35:13 jh-mba kernel: Call Trace:
Jul 18 14:35:13 jh-mba kernel: audit_log_d_path+0x75/0xd0
Jul 18 14:35:13 jh-mba kernel: audit_log_exit+0x63d/0xcf0
Jul 18 14:35:13 jh-mba kernel: ? audit_log_d_path+0x75/0xd0
Jul 18 14:35:13 jh-mba kernel: ? audit_filter_inodes+0x2e/0x100
Jul 18 14:35:13 jh-mba kernel: __audit_free+0x233/0x260
Jul 18 14:35:13 jh-mba kernel: do_exit+0x8d3/0xb50
Jul 18 14:35:13 jh-mba kernel: ? syscall_slow_exit_work+0x117/0x140
Jul 18 14:35:13 jh-mba kernel: rewind_stack_do_exit+0x17/0x20
Jul 18 14:35:13 jh-mba kernel: RIP: 0033:0x7ff689f8eb67
Jul 18 14:35:13 jh-mba kernel: Code: 73 01 c3 48 8b 0d 29 d3 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 07 01 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d f9 d2 0c 00 f7 d8 64 89 01 48
Jul 18 14:35:13 jh-mba kernel: RSP: 002b:00007fff95e52468 EFLAGS: 00000246 ORIG_RAX: 0000000000000107
Jul 18 14:35:13 jh-mba kernel: RAX: 0000000000000000 RBX: 00007ff68934e830 RCX: 00007ff689f8eb67
Jul 18 14:35:13 jh-mba kernel: RDX: 0000000000000000 RSI: 000055edb4e490b3 RDI: 0000000000000004
Jul 18 14:35:13 jh-mba kernel: RBP: 0000000000000004 R08: 000055edb4e490a0 R09: 00007ff68a05cbe0
Jul 18 14:35:13 jh-mba kernel: R10: 0000000000000004 R11: 0000000000000246 R12: 000055edb4e49040
Jul 18 14:35:13 jh-mba kernel: R13: 0000000000000000 R14: 000055edb4e490a0 R15: 000055edb4e490b3
Jul 18 14:35:13 jh-mba kernel: Modules linked in: rfcomm bnep xt_CHECKSUM cpufreq_powersave xt_MASQUERADE cpufreq_conservative cpufreq_userspace xt_tcpudp nft_compat bridge stp llc overlay fuse nft_chain_nat nf_nat nf_log_ipv6 nf_log_ipv4 nf_log_common nft_log veth intel_rapl_msr btusb btrtl btbcm joydev binfmt_misc btintel nls_ascii nls_cp437 vfat fat bluetooth nft_counter drbg intel_rapl_common asix ansi_cprng ecdh_generic usbnet ecc mii vrf libphy x86_pkg_temp_thermal intel_powerclamp applesmc snd_hda_codec_hdmi snd_hda_codec_cirrus snd_hda_codec_generic coretemp ledtrig_audio evdev wireguard kvm_intel curve25519_x86_64 libcurve25519_generic libchacha20poly1305 snd_hda_intel kvm bcm5974 wl(POE) snd_intel_dspcfg chacha_x86_64 poly1305_x86_64 ip6_udp_tunnel efi_pstore udp_tunnel irqbypass snd_hda_codec libblake2s cfg80211 intel_cstate snd_hda_core blake2s_x86_64 libblake2s_generic libchacha snd_hwdep intel_uncore iTCO_wdt i915 iTCO_vendor_support intel_rapl_perf snd_pcm nft_ct sg efivars pcspkr nf_conntrack
Jul 18 14:35:13 jh-mba kernel: watchdog rfkill snd_timer nf_defrag_ipv6 nf_defrag_ipv4 drm_kms_helper mei_me snd mei cec soundcore i2c_algo_bit sbs sbshc acpi_als kfifo_buf industrialio apple_bl ac button bonding nf_tables parport_pc(E) nfnetlink ppdev(E) lp(E) drm parport(E) sunrpc efivarfs ip_tables x_tables autofs4 ext4 crc16 mbcache jbd2 btrfs blake2b_generic zstd_decompress zstd_compress hid_apple hid_generic usbhid hid dm_crypt dm_mod raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c crc32c_generic raid1 raid0 multipath linear md_mod uas usb_storage sd_mod t10_pi crc_t10dif crct10dif_generic crct10dif_pclmul crct10dif_common crc32_pclmul crc32c_intel ghash_clmulni_intel ahci libahci xhci_pci aesni_intel xhci_hcd libaes crypto_simd libata cryptd glue_helper usbcore scsi_mod i2c_i801 thunderbolt lpc_ich mfd_core usb_common spi_pxa2xx_platform dw_dmac video dw_dmac_core
Jul 18 14:35:13 jh-mba kernel: CR2: 0000000000000060
Jul 18 14:35:13 jh-mba kernel: ---[ end trace 01b46d19ab2d30c0 ]---
Jul 18 14:35:13 jh-mba kernel: RIP: 0010:d_path+0x35/0x140
Jul 18 14:35:13 jh-mba kernel: Code: 49 89 fc 48 83 ec 28 48 8b 7f 08 89 54 24 04 65 48 8b 04 25 28 00 00 00 48 89 44 24 20 31 c0 48 63 c2 48 01 f0 48 89 44 24 08 <48> 8b 47 60 48 85 c0 74 22 48 8b 40 48 48 85 c0 74 19 48 3b 7f 18
Jul 18 14:35:13 jh-mba kernel: RSP: 0018:ffffb71e411cfe18 EFLAGS: 00010282
Jul 18 14:35:13 jh-mba kernel: RAX: ffff9a525f18700b RBX: ffff9a524fc52060 RCX: 00000000000004dd
Jul 18 14:35:13 jh-mba kernel: RDX: 000000000000100b RSI: ffff9a525f186000 RDI: 0000000000000000
Jul 18 14:35:13 jh-mba kernel: RBP: ffffb71e411cfe48 R08: ffff9a52672b0060 R09: 0000000000000006
Jul 18 14:35:13 jh-mba kernel: R10: ffff9a522c99e6c0 R11: ffff9a532c99e030 R12: ffff9a524fc522b0
Jul 18 14:35:13 jh-mba kernel: R13: ffff9a52658d3708 R14: ffff9a524fc52000 R15: 0000000000000000
Jul 18 14:35:13 jh-mba kernel: FS: 00007ff68934e980(0000) GS:ffff9a5267280000(0000) knlGS:0000000000000000
Jul 18 14:35:13 jh-mba kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Jul 18 14:35:13 jh-mba kernel: CR2: 0000000000000060 CR3: 0000000226ce6002 CR4: 00000000001606e0
Jul 18 14:35:13 jh-mba kernel: Fixing recursive fault but reboot is needed!
Jul 18 14:35:10 jh-mba audit[3163]: SYSCALL arch=c000003e syscall=263 a0=4 a1=55edb4e490b3 a2=0 a3=4 items=2 ppid=1 pid=3163 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="systemd-user-ru" exe="/usr/lib/systemd/systemd-user-runtime-dir" subj=system_u:system_r:systemd_user_runtime_dir_t:s0 key=(null)
Jul 18 14:35:14 jh-mba systemd[1]: systemd-hostnamed.service: Succeeded.
Jul 18 14:35:14 jh-mba audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=systemd-hostnamed comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
Line information from the debian linux-image-5.7.0-1-amd64 (version 5.7.6-1) package, duplicates ommitted:
Reading symbols from /usr/lib/debug/boot/vmlinux-5.7.0-1-amd64...
(gdb) l *d_path+0x35
0xffffffff812dcee5 is in d_path (fs/d_path.c:275).
270 *
271 * Some pseudo inodes are mountable. When they are mounted
272 * path->dentry == path->mnt->mnt_root. In that case don't call d_dname
273 * and instead have d_path return the mounted path.
274 */
275 if (path->dentry->d_op && path->dentry->d_op->d_dname &&
276 (!IS_ROOT(path->dentry) || path->dentry != path->mnt->mnt_root))
277 return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
278
279 rcu_read_lock();
(gdb) l *audit_log_d_path+0x75
0xffffffff8114f175 is in audit_log_d_path (kernel/audit.c:2046).
2041 pathname = kmalloc(PATH_MAX+11, ab->gfp_mask);
2042 if (!pathname) {
2043 audit_log_string(ab, "<no_memory>");
2044 return;
2045 }
2046 p = d_path(path, pathname, PATH_MAX+11);
2047 if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
2048 /* FIXME: can we save some information here? */
2049 audit_log_string(ab, "<too_long>");
2050 } else
(gdb) l *audit_log_exit+0x63d
0xffffffff8115445d is in audit_log_exit (kernel/auditsc.c:1342).
1337 case 0:
1338 /* name was specified as a relative path and the
1339 * directory component is the cwd
1340 */
1341 audit_log_d_path(ab, " name=", &context->pwd);
1342 break;
1343 default:
1344 /* log the name's directory component */
1345 audit_log_format(ab, " name=");
1346 audit_log_n_untrustedstring(ab, n->name->name,
(gdb) l *audit_filter_inodes+0x2e
0xffffffff81155e2e is in audit_filter_inodes (kernel/auditsc.c:835).
830 */
831 void audit_filter_inodes(struct task_struct *tsk, struct audit_context *ctx)
832 {
833 struct audit_names *n;
834
835 if (auditd_test_task(tsk))
836 return;
837
838 rcu_read_lock();
839
(gdb) l *__audit_syscall_exit+0x23b
0xffffffff8115661b is in __audit_syscall_exit (kernel/auditsc.c:1710).
1705
1706 audit_filter_syscall(current, context,
1707 &audit_filter_list[AUDIT_FILTER_EXIT]);
1708 audit_filter_inodes(current, context);
1709 if (context->current_state == AUDIT_RECORD_CONTEXT)
1710 audit_log_exit();
1711 }
1712
1713 context->in_syscall = 0;
1714 context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0;
(gdb) l *syscall_slow_exit_work+0x117
0xffffffff81005197 is in syscall_slow_exit_work (include/linux/audit.h:316).
311 {
312 if (unlikely(audit_context())) {
313 int success = is_syscall_success(pt_regs);
314 long return_code = regs_return_value(pt_regs);
315
316 __audit_syscall_exit(success, return_code);
317 }
318 }
319 static inline struct filename *audit_reusename(const __user char *name)
320 {
(gdb) l *do_syscall_64+0x10e
0xffffffff8100543e is in do_syscall_64 (arch/x86/entry/common.c:276).
warning: Source file is more recent than executable.
271 /*
272 * First do one-time work. If these work items are enabled, we
273 * want to run them exactly once per syscall exit with IRQs on.
274 */
275 if (unlikely(cached_flags & SYSCALL_EXIT_WORK_FLAGS))
276 syscall_slow_exit_work(regs, cached_flags);
277
278 local_irq_disable();
279 prepare_exit_to_usermode(regs);
280 }
(gdb) l *entry_SYSCALL_64_after_hwframe+0x44
0xffffffff8180008c is at /build/linux-iTqI2R/linux-5.7.6/arch/x86/entry/entry_64.S:184.
179 /build/linux-iTqI2R/linux-5.7.6/arch/x86/entry/entry_64.S: No such file or directory.
(gdb) l *__audit_free+0x233
0xffffffff81156283 is in __audit_free (kernel/auditsc.c:1602).
1597
1598 audit_filter_syscall(tsk, context,
1599 &audit_filter_list[AUDIT_FILTER_EXIT]);
1600 audit_filter_inodes(tsk, context);
1601 if (context->current_state == AUDIT_RECORD_CONTEXT)
1602 audit_log_exit();
1603 }
1604
1605 audit_set_context(tsk, NULL);
1606 audit_free_context(context);
(gdb) l *do_exit+0x8d3
0xffffffff81088ce3 is in do_exit (include/linux/audit.h:301).
296 return !p || *(int *)p;
297 }
298 static inline void audit_free(struct task_struct *task)
299 {
300 if (unlikely(task->audit_context))
301 __audit_free(task);
302 }
303 static inline void audit_syscall_entry(int major, unsigned long a0,
304 unsigned long a1, unsigned long a2,
305 unsigned long a3)
(gdb) l *syscall_slow_exit_work+0x117
0xffffffff81005197 is in syscall_slow_exit_work (include/linux/audit.h:316).
311 {
312 if (unlikely(audit_context())) {
313 int success = is_syscall_success(pt_regs);
314 long return_code = regs_return_value(pt_regs);
315
316 __audit_syscall_exit(success, return_code);
317 }
318 }
319 static inline struct filename *audit_reusename(const __user char *name)
320 {
(gdb) l *rewind_stack_do_exit+0x17
(gdb)
--
bauen1
https://dn42.bauen1.xyz/
4 years, 3 months
[PATCH v3] audit: report audit wait metric in audit status reply
by Max Englander
In environments where the preservation of audit events and predictable
usage of system memory are prioritized, admins may use a combination of
--backlog_wait_time and -b options at the risk of degraded performance
resulting from backlog waiting. In some cases, this risk may be
preferred to lost events or unbounded memory usage. Ideally, this risk
can be mitigated by making adjustments when backlog waiting is detected.
However, detection can be difficult using the currently available
metrics. For example, an admin attempting to debug degraded performance
may falsely believe a full backlog indicates backlog waiting. It may
turn out the backlog frequently fills up but drains quickly.
To make it easier to reliably track degraded performance to backlog
waiting, this patch makes the following changes:
Add a new field backlog_wait_time_total to the audit status reply.
Initialize this field to zero. Add to this field the total time spent
by the current task on scheduled timeouts while the backlog limit is
exceeded. Reset field to zero upon request via AUDIT_SET.
Tested on Ubuntu 18.04 using complementary changes to the
audit-userspace and audit-testsuite:
- https://github.com/linux-audit/audit-userspace/pull/134
- https://github.com/linux-audit/audit-testsuite/pull/97
Signed-off-by: Max Englander <max.englander(a)gmail.com>
---
Patch changelogs between v1 and v2:
- Instead of printing a warning when backlog waiting occurs, add
duration of backlog waiting to cumulative sum, and report this
sum in audit status reply.
Patch changelogs between v2 and v3:
- Rename backlog_wait_sum to backlog_wait_time_actual.
- Drop unneeded and unwanted header flags
AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_SUM and
AUDIT_VERSION_BACKLOG_WAIT_SUM.
- Increment backlog_wait_time_actual counter after every call to
schedule_timeout rather than once after enqueuing (or losing) an
audit record.
- Add support for resetting backlog_wait_time_actual counter to zero
upon request via AUDIT_SET.
include/uapi/linux/audit.h | 18 +++++++++++-------
kernel/audit.c | 35 +++++++++++++++++++++++++----------
2 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index a534d71e689a..92d72965ad44 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -332,14 +332,15 @@ enum {
};
/* Status symbols */
- /* Mask values */
-#define AUDIT_STATUS_ENABLED 0x0001
-#define AUDIT_STATUS_FAILURE 0x0002
-#define AUDIT_STATUS_PID 0x0004
+ /* Mask values */
+#define AUDIT_STATUS_ENABLED 0x0001
+#define AUDIT_STATUS_FAILURE 0x0002
+#define AUDIT_STATUS_PID 0x0004
#define AUDIT_STATUS_RATE_LIMIT 0x0008
-#define AUDIT_STATUS_BACKLOG_LIMIT 0x0010
-#define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
-#define AUDIT_STATUS_LOST 0x0040
+#define AUDIT_STATUS_BACKLOG_LIMIT 0x0010
+#define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
+#define AUDIT_STATUS_LOST 0x0040
+#define AUDIT_STATUS_BACKLOG_WAIT_TIME_ACTUAL 0x0080
#define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT 0x00000001
#define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002
@@ -466,6 +467,9 @@ struct audit_status {
__u32 feature_bitmap; /* bitmap of kernel audit features */
};
__u32 backlog_wait_time;/* message queue wait timeout */
+ __u32 backlog_wait_time_actual;/* time spent waiting while
+ * message limit exceeded
+ */
};
struct audit_features {
diff --git a/kernel/audit.c b/kernel/audit.c
index 87f31bf1f0a0..33c640fdacf7 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -136,6 +136,11 @@ u32 audit_sig_sid = 0;
*/
static atomic_t audit_lost = ATOMIC_INIT(0);
+/* Monotonically increasing sum of time the kernel has spent
+ * waiting while the backlog limit is exceeded.
+ */
+static atomic_t audit_backlog_wait_time_actual = ATOMIC_INIT(0);
+
/* Hash for inode-based rules */
struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
@@ -1193,17 +1198,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_GET: {
struct audit_status s;
memset(&s, 0, sizeof(s));
- s.enabled = audit_enabled;
- s.failure = audit_failure;
+ s.enabled = audit_enabled;
+ s.failure = audit_failure;
/* NOTE: use pid_vnr() so the PID is relative to the current
* namespace */
- s.pid = auditd_pid_vnr();
- s.rate_limit = audit_rate_limit;
- s.backlog_limit = audit_backlog_limit;
- s.lost = atomic_read(&audit_lost);
- s.backlog = skb_queue_len(&audit_queue);
- s.feature_bitmap = AUDIT_FEATURE_BITMAP_ALL;
- s.backlog_wait_time = audit_backlog_wait_time;
+ s.pid = auditd_pid_vnr();
+ s.rate_limit = audit_rate_limit;
+ s.backlog_limit = audit_backlog_limit;
+ s.lost = atomic_read(&audit_lost);
+ s.backlog = skb_queue_len(&audit_queue);
+ s.feature_bitmap = AUDIT_FEATURE_BITMAP_ALL;
+ s.backlog_wait_time = audit_backlog_wait_time;
+ s.backlog_wait_time_actual = atomic_read(&audit_backlog_wait_time_actual);
audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s));
break;
}
@@ -1307,6 +1313,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
audit_log_config_change("lost", 0, lost, 1);
return lost;
}
+ if (s.mask == AUDIT_STATUS_BACKLOG_WAIT_TIME_ACTUAL) {
+ u32 actual = atomic_xchg(&audit_backlog_wait_time_actual, 0);
+
+ audit_log_config_change("backlog_wait_time_actual", 0, actual, 1);
+ return actual;
+ }
break;
}
case AUDIT_GET_FEATURE:
@@ -1778,12 +1790,15 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
/* sleep if we are allowed and we haven't exhausted our
* backlog wait limit */
if (gfpflags_allow_blocking(gfp_mask) && (stime > 0)) {
+ long rtime = stime;
+
DECLARE_WAITQUEUE(wait, current);
add_wait_queue_exclusive(&audit_backlog_wait,
&wait);
set_current_state(TASK_UNINTERRUPTIBLE);
- stime = schedule_timeout(stime);
+ stime = schedule_timeout(rtime);
+ atomic_add(rtime - stime, &audit_backlog_wait_time_actual);
remove_wait_queue(&audit_backlog_wait, &wait);
} else {
if (audit_rate_check() && printk_ratelimit())
--
2.17.1
4 years, 3 months
[PATCH ghak84 v4] audit: purge audit_log_string from the intra-kernel audit API
by Richard Guy Briggs
audit_log_string() was inteded to be an internal audit function and
since there are only two internal uses, remove them. Purge all external
uses of it by restructuring code to use an existing audit_log_format()
or using audit_log_format().
Please see the upstream issue
https://github.com/linux-audit/audit-kernel/issues/84
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Passes audit-testsuite.
Changelog:
v4
- use double quotes in all replaced audit_log_string() calls
v3
- fix two warning: non-void function does not return a value in all control paths
Reported-by: kernel test robot <lkp(a)intel.com>
v2
- restructure to piggyback on existing audit_log_format() calls, checking quoting needs for each.
v1 Vlad Dronov
- https://github.com/nefigtut/audit-kernel/commit/dbbcba46335a002f44b058741...
include/linux/audit.h | 5 -----
kernel/audit.c | 4 ++--
security/apparmor/audit.c | 10 ++++------
security/apparmor/file.c | 25 +++++++------------------
security/apparmor/ipc.c | 46 +++++++++++++++++++++++-----------------------
security/apparmor/net.c | 14 ++++++++------
security/lsm_audit.c | 4 ++--
7 files changed, 46 insertions(+), 62 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 523f77494847..b3d859831a31 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -694,9 +694,4 @@ static inline bool audit_loginuid_set(struct task_struct *tsk)
return uid_valid(audit_get_loginuid(tsk));
}
-static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
-{
- audit_log_n_string(ab, buf, strlen(buf));
-}
-
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index 8c201f414226..a2f3e34aa724 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2080,13 +2080,13 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
/* We will allow 11 spaces for ' (deleted)' to be appended */
pathname = kmalloc(PATH_MAX+11, ab->gfp_mask);
if (!pathname) {
- audit_log_string(ab, "<no_memory>");
+ audit_log_format(ab, "\"<no_memory>\"");
return;
}
p = d_path(path, pathname, PATH_MAX+11);
if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
/* FIXME: can we save some information here? */
- audit_log_string(ab, "<too_long>");
+ audit_log_format(ab, "\"<too_long>\"");
} else
audit_log_untrustedstring(ab, p);
kfree(pathname);
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 597732503815..f7e97c7e80f3 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -57,18 +57,16 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
struct common_audit_data *sa = ca;
if (aa_g_audit_header) {
- audit_log_format(ab, "apparmor=");
- audit_log_string(ab, aa_audit_type[aad(sa)->type]);
+ audit_log_format(ab, "apparmor=\"%s\"",
+ aa_audit_type[aad(sa)->type]);
}
if (aad(sa)->op) {
- audit_log_format(ab, " operation=");
- audit_log_string(ab, aad(sa)->op);
+ audit_log_format(ab, " operation=\"%s\"", aad(sa)->op);
}
if (aad(sa)->info) {
- audit_log_format(ab, " info=");
- audit_log_string(ab, aad(sa)->info);
+ audit_log_format(ab, " info=\"%s\"", aad(sa)->info);
if (aad(sa)->error)
audit_log_format(ab, " error=%d", aad(sa)->error);
}
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 9a2d14b7c9f8..92acf9a49405 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -35,20 +35,6 @@ static u32 map_mask_to_chr_mask(u32 mask)
}
/**
- * audit_file_mask - convert mask to permission string
- * @buffer: buffer to write string to (NOT NULL)
- * @mask: permission mask to convert
- */
-static void audit_file_mask(struct audit_buffer *ab, u32 mask)
-{
- char str[10];
-
- aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
- map_mask_to_chr_mask(mask));
- audit_log_string(ab, str);
-}
-
-/**
* file_audit_cb - call back for file specific audit fields
* @ab: audit_buffer (NOT NULL)
* @va: audit struct to audit values of (NOT NULL)
@@ -57,14 +43,17 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
{
struct common_audit_data *sa = va;
kuid_t fsuid = current_fsuid();
+ char str[10];
if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " requested_mask=");
- audit_file_mask(ab, aad(sa)->request);
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+ map_mask_to_chr_mask(aad(sa)->request));
+ audit_log_format(ab, " requested_mask=\"%s\"", str);
}
if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " denied_mask=");
- audit_file_mask(ab, aad(sa)->denied);
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+ map_mask_to_chr_mask(aad(sa)->denied));
+ audit_log_format(ab, " denied_mask=\"%s\"", str);
}
if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
audit_log_format(ab, " fsuid=%d",
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index 4ecedffbdd33..fe36d112aad9 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -20,25 +20,23 @@
/**
* audit_ptrace_mask - convert mask to permission string
- * @buffer: buffer to write string to (NOT NULL)
* @mask: permission mask to convert
+ *
+ * Returns: pointer to static string
*/
-static void audit_ptrace_mask(struct audit_buffer *ab, u32 mask)
+static const char *audit_ptrace_mask(u32 mask)
{
switch (mask) {
case MAY_READ:
- audit_log_string(ab, "read");
- break;
+ return "read";
case MAY_WRITE:
- audit_log_string(ab, "trace");
- break;
+ return "trace";
case AA_MAY_BE_READ:
- audit_log_string(ab, "readby");
- break;
+ return "readby";
case AA_MAY_BE_TRACED:
- audit_log_string(ab, "tracedby");
- break;
+ return "tracedby";
}
+ return "";
}
/* call back to audit ptrace fields */
@@ -47,12 +45,12 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
struct common_audit_data *sa = va;
if (aad(sa)->request & AA_PTRACE_PERM_MASK) {
- audit_log_format(ab, " requested_mask=");
- audit_ptrace_mask(ab, aad(sa)->request);
+ audit_log_format(ab, " requested_mask=\"%s\"",
+ audit_ptrace_mask(aad(sa)->request));
if (aad(sa)->denied & AA_PTRACE_PERM_MASK) {
- audit_log_format(ab, " denied_mask=");
- audit_ptrace_mask(ab, aad(sa)->denied);
+ audit_log_format(ab, " denied_mask=\"%s\"",
+ audit_ptrace_mask(aad(sa)->denied));
}
}
audit_log_format(ab, " peer=");
@@ -142,16 +140,18 @@ static inline int map_signal_num(int sig)
}
/**
- * audit_file_mask - convert mask to permission string
- * @buffer: buffer to write string to (NOT NULL)
+ * audit_signal_mask - convert mask to permission string
* @mask: permission mask to convert
+ *
+ * Returns: pointer to static string
*/
-static void audit_signal_mask(struct audit_buffer *ab, u32 mask)
+static const char *audit_signal_mask(u32 mask)
{
if (mask & MAY_READ)
- audit_log_string(ab, "receive");
+ return "receive";
if (mask & MAY_WRITE)
- audit_log_string(ab, "send");
+ return "send";
+ return "";
}
/**
@@ -164,11 +164,11 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va)
struct common_audit_data *sa = va;
if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
- audit_log_format(ab, " requested_mask=");
- audit_signal_mask(ab, aad(sa)->request);
+ audit_log_format(ab, " requested_mask=\"%s\"",
+ audit_signal_mask(aad(sa)->request));
if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
- audit_log_format(ab, " denied_mask=");
- audit_signal_mask(ab, aad(sa)->denied);
+ audit_log_format(ab, " denied_mask=\"%s\"",
+ audit_signal_mask(aad(sa)->denied));
}
}
if (aad(sa)->signal == SIGUNKNOWN)
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index d8afc39f663a..fa0e85568450 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -72,16 +72,18 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
{
struct common_audit_data *sa = va;
- audit_log_format(ab, " family=");
if (address_family_names[sa->u.net->family])
- audit_log_string(ab, address_family_names[sa->u.net->family]);
+ audit_log_format(ab, " family=\"%s\"",
+ address_family_names[sa->u.net->family]);
else
- audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
- audit_log_format(ab, " sock_type=");
+ audit_log_format(ab, " family=\"unknown(%d)\"",
+ sa->u.net->family);
if (sock_type_names[aad(sa)->net.type])
- audit_log_string(ab, sock_type_names[aad(sa)->net.type]);
+ audit_log_format(ab, " sock_type=\"%s\"",
+ sock_type_names[aad(sa)->net.type]);
else
- audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type);
+ audit_log_format(ab, " sock_type=\"unknown(%d)\"",
+ aad(sa)->net.type);
audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
if (aad(sa)->request & NET_PERMS_MASK) {
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 7c555621c2bd..53d0d183db8f 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -432,8 +432,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
a->u.ibendport->port);
break;
case LSM_AUDIT_DATA_LOCKDOWN:
- audit_log_format(ab, " lockdown_reason=");
- audit_log_string(ab, lockdown_reasons[a->u.reason]);
+ audit_log_format(ab, " lockdown_reason=\"%s\"",
+ lockdown_reasons[a->u.reason]);
break;
} /* switch (a->type) */
}
--
1.8.3.1
4 years, 3 months
[RFC PATCH v4 00/12] Integrity Policy Enforcement LSM (IPE)
by Deven Bowers
Overview:
------------------------------------
IPE is a Linux Security Module which allows for a configurable
policy to enforce integrity requirements on the whole system. It
attempts to solve the issue of Code Integrity: that any code being
executed (or files being read), are identical to the version that
was built by a trusted source.
The type of system for which IPE is designed for use is an embedded device
with a specific purpose (e.g. network firewall device in a data center),
where all software and configuration is built and provisioned by the owner.
Specifically, a system which leverages IPE is not intended for general
purpose computing and does not utilize any software or configuration
built by a third party. An ideal system to leverage IPE has both mutable
and immutable components, however, all binary executable code is immutable.
The scope of IPE is constrained to the OS. It is assumed that platform
firmware verifies the the kernel and optionally the root filesystem (e.g.
via U-Boot verified boot). IPE then utilizes LSM hooks to enforce a
flexible, kernel-resident integrity verification policy.
IPE differs from other LSMs which provide integrity checking (for instance,
IMA), as it has no dependency on the filesystem metadata itself. The
attributes that IPE checks are deterministic properties that exist solely
in the kernel. Additionally, IPE provides no additional mechanisms of
verifying these files (e.g. IMA Signatures) - all of the attributes of
verifying files are existing features within the kernel, such as dm-verity
or fsverity.
IPE provides a policy that allows owners of the system to easily specify
integrity requirements and uses dm-verity signatures to simplify the
authentication of allowed objects like authorized code and data.
IPE supports two modes, permissive (similar to SELinux's permissive mode)
and enforce. Permissive mode performs the same checks, and logs policy
violations as enforce mode, but will not enforce the policy. This allows
users to test policies before enforcing them.
The default mode is enforce, and can be changed via the kernel commandline
parameter `ipe.enforce=(0|1)`, or the securityfs node
`/sys/kernel/security/ipe/enforce`. The ability to switch modes can be
compiled out of the LSM via setting the config
CONFIG_SECURITY_IPE_PERMISSIVE_SWITCH to N.
IPE additionally supports success auditing. When enabled, all events
that pass IPE policy and are not blocked will emit an audit event. This
is disabled by default, and can be enabled via the kernel commandline
`ipe.success_audit=(0|1)` or the securityfs node
`/sys/kernel/security/ipe/success_audit`.
Policies can be staged at runtime through securityfs and activated through
sysfs. Please see the Deploying Policies section of this cover letter for
more information.
The IPE LSM is compiled under CONFIG_SECURITY_IPE.
Policy:
------------------------------------
IPE policy is designed to be both forward compatible and backwards
compatible. There is one required line, at the top of the policy,
indicating the policy name, and the policy version, for instance:
policy_name="Ex Policy" policy_version=0.0.0
The policy version indicates the current version of the policy (NOT the
policy syntax version). This is used to prevent roll-back of policy to
potentially insecure previous versions of the policy.
The next portion of IPE policy, are rules. Rules are formed by key=value
pairs, known as properties. IPE rules require two properties: "action",
which determines what IPE does when it encounters a match against the
policy, and "op", which determines when that rule should be evaluated.
Thus, a minimal rule is:
op=EXECUTE action=ALLOW
This example will allow any execution. Additional properties are used to
restrict attributes about the files being evaluated. These properties are
intended to be deterministic attributes that are resident in the kernel.
Available properties for IPE described in the properties section of this
cover-letter, the repository available in Appendix A, and the kernel
documentation page.
Order does not matter for the rule's properties - they can be listed in
any order, however it is encouraged to have the "op" property be first,
and the "action" property be last, for readability.
Additionally, rules are evaluated top-to-bottom. As a result, any
revocation rules, or denies should be placed early in the file to ensure
that these rules are evaluated before a rule with "action=ALLOW" is hit.
Any unknown syntax in IPE policy will result in a fatal error to parse
the policy. User mode can interrogate the kernel to understand what
properties and the associated versions through the securityfs node,
$securityfs/ipe/property_config, which will return a string of form:
key1=version1
key2=version2
.
.
.
keyN=versionN
User-mode should correlate these versions with the supported values
identified in the documentation to determine whether a policy should
be accepted by the system.
Additionally, a DEFAULT operation must be set for all understood
operations within IPE. For policies to remain completely forwards
compatible, it is recommended that users add a "DEFAULT action=ALLOW"
and override the defaults on a per-operation basis.
For more information about the policy syntax, please see Appendix A or
the kernel documentation page.
Early Usermode Protection:
--------------------------
IPE can be provided with a policy at startup to load and enforce.
This is intended to be a minimal policy to get the system to a state
where userland is setup and ready to receive commands, at which
point a policy can be deployed via securityfs. This "boot policy" can be
specified via the config, SECURITY_IPE_BOOT_POLICY, which accepts a path
to a plain-text version of the IPE policy to apply. This policy will be
compiled into the kernel. If not specified, IPE will be disabled until a
policy is deployed and activated through the method above.
Policy Examples:
------------------------------------
Allow all:
policy_name="Allow All" policy_version=0.0.0
DEFAULT action=ALLOW
Allow only initial superblock:
policy_name="Allow All Initial SB" policy_version=0.0.0
DEFAULT action=DENY
op=EXECUTE boot_verified=TRUE action=ALLOW
Allow any signed dm-verity volume and the initial superblock:
policy_name="AllowSignedAndInitial" policy_version=0.0.0
DEFAULT action=DENY
op=EXECUTE boot_verified=TRUE action=ALLOW
op=EXECUTE dmverity_signature=TRUE action=ALLOW
Prohibit execution from a specific dm-verity volume:
policy_name="AllowSignedAndInitial" policy_version=0.0.0
DEFAULT action=DENY
op=EXECUTE dmverity_roothash=401fcec5944823ae12f62726e8184407a5fa9599783f030dec146938 action=DENY
op=EXECUTE boot_verified=TRUE action=ALLOW
op=EXECUTE dmverity_signature=TRUE action=ALLOW
Allow only a specific dm-verity volume:
policy_name="AllowSignedAndInitial" policy_version=0.0.0
DEFAULT action=DENY
op=EXECUTE dmverity_roothash=401fcec5944823ae12f62726e8184407a5fa9599783f030dec146938 action=ALLOW
Deploying Policies:
-------------------
Deploying policies is simple. First sign a plain text policy, with a
certificate that is present in the SYSTEM_TRUSTED_KEYRING of your test
machine. Through openssl, the signing can be done via:
openssl smime -sign -in "$MY_POLICY" -signer "$MY_CERTIFICATE" \
-inkey "$MY_PRIVATE_KEY" -binary -outform der -noattr -nodetach \
-out "$MY_POLICY.p7s"
Then, simply cat the file into the IPE's "new_policy" securityfs node:
cat "$MY_POLICY.p7s" > /sys/kernel/security/ipe/new_policy
The policy should now be present under the policies/ subdirectory, under
its "policy_name" attribute.
The policy is now present in the kernel and can be marked as active,
via the sysctl "ipe.active_policy":
echo -n 1 > "/sys/kernel/security/ipe/$MY_POLICY_NAME/active"
This will now mark the policy as active and the system will be enforcing
$MY_POLICY_NAME. At any point the policy can be updated on the provision
that the policy version to be deployed is greater than or equal to the
running version (to prevent roll-back attacks). This update can be done
by redirecting the file into the policy's "raw" node, under the policies
subdirectory:
cat "$MY_UPDATED_POLICY.p7s" > \
"/sys/kernel/security/ipe/policies/$MY_POLICY_NAME/raw"
Additionally, policies can be deleted via the "del_policy" securityfs
node. Simply write the name of the policy to be deleted to that node:
echo -n 1 >
"/sys/kernel/security/ipe/policies/$MY_POLICY_NAME/delete"
There are two requirements to delete policies:
1. The policy being deleted must not be the active policy.
2. The policy being deleted must not be the boot policy.
It's important to know above that the "echo" command will add a newline
to the end of the input, and this will be considered as part of the
filename. You can remove the newline via the -n parameter.
NOTE: If a MAC LSM is enabled, the securityfs commands will require
CAP_MAC_ADMIN. This is due to sysfs supporting fine-grained MAC
attributes, while securityfs at the current moment does not.
Properties:
------------------------------------
This initial patchset introducing IPE adds three properties:
'boot_verified', 'dmverity_signature' and 'dmverity_roothash'.
boot_verified (CONFIG_IPE_BOOT_PROP):
This property can be utilized for authorization of the first
super-block that is mounted on the system, where IPE attempts
to evaluate a file. Typically this is used for systems with
an initramfs or other initial disk, where this is unmounted before
the system becomes available, and is not covered by any other property.
The format of this property is:
boot_verified=(TRUE|FALSE)
WARNING: This property will trust any disk where the first IPE
evaluation occurs. If you do not have a startup disk that is
unpacked and unmounted (like initramfs), then it will automatically
trust the root filesystem and potentially overauthorize the entire
disk.
dmverity_roothash (CONFIG_IPE_DM_VERITY_ROOTHASH):
This property can be utilized for authorization or revocation of
specific dmverity volumes, identified via root hash. It has a
dependency on the DM_VERITY module. The format of this property is:
dmverity_roothash=<HashHexDigest>
dmverity_signature (CONFIG_IPE_DM_VERITY_SIGNATURE):
This property can be utilized for authorization of all dm-verity
volumes that have a signed roothash that chains to the system
trusted keyring. It has a dependency on the
DM_VERITY_VERIFY_ROOTHASH_SIG config. The format of this property is:
dmverity_signature=(TRUE|FALSE)
Testing:
------------------------------------
A test suite is available (Appendix B) for ease of use. For manual
instructions:
Enable IPE through the following Kconfigs:
CONFIG_SECURITY_IPE=y
CONFIG_SECURITY_IPE_BOOT_POLICY="../AllowAllInitialSB.pol"
CONFIG_SECURITY_IPE_PERMISSIVE_SWITCH=y
CONFIG_IPE_BOOT_PROP=y
CONFIG_IPE_DM_VERITY_ROOTHASH=y
CONFIG_IPE_DM_VERITY_SIGNATURE=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS="/path/to/my/cert/list.pem"
Start a test system, that boots directly from the filesystem, without
an initrd. I recommend testing in permissive mode until all tests
pass, then switch to enforce to ensure behavior remains identical.
boot_verified:
If booted correctly, the filesystem mounted on / should be marked as
boot_verified. Verify by turning on success auditing (sysctl
ipe.success_audit=1), and run a binary. In the audit output,
`prop_boot_verified` should be `TRUE`.
To test denials, mount a temporary filesystem (mount -t tmpfs -o
size=4M tmp tmp), and copy a binary (e.g. ls) to this new
filesystem. Disable success auditing and attempt to run the file.
The file should have an audit event, but be allowed to execute in
permissive mode, and prop_boot_verified should be FALSE.
dmverity_roothash:
First, you must create a dm-verity volume. This can be done through
squashfs-tools and veritysetup (provided by cryptsetup).
Creating a squashfs volume:
mksquashfs /path/to/directory/with/executable /path/to/output.squashfs
Format the volume for use with dm-verity & save the root hash:
output_rh=$(veritysetup format output.squashfs output.hashtree | \
tee verity_out.txt | awk "/Root hash/" | \
sed -E "s/Root hash:\s+//g")
echo -n $output_rh > output.roothash
Create a two policies, filling in the appropriate fields below:
Policy 1:
policy_name="roothash-denial" policy_version=0.0.0
DEFAULT action=ALLOW
op=EXECUTE dmverity_roothash=$output_rh action=DENY
Policy 2:
policy_name="roothash-allow" policy_version=0.0.0
DEFAULT action=ALLOW
DEFAULT op=EXECUTE action=DENY
op=EXECUTE boot_verified=TRUE action=ALLOW
op=EXECUTE dmverity_roothash=$output_rh action=ALLOW
Deploy each policy, then mark the first, "roothash-denial" as active,
per the "Deploying Policies" section of this cover letter. Mount the
dm-verity volume:
veritysetup open output.squashfs output.hashtree unverified \
`cat output.roothash`
mount /dev/mapper/unverified /my/mount/point
Attempt to execute a binary in the mount point, and it should emit an
audit event for a match against the rule:
op=EXECUTE dmverity_roothash=$output_rh action=DENY
To test the second policy, perform the same steps, but this time, enable
success auditing before running the executable. The success audit event
should be a match against this rule:
op=EXECUTE dmverity_roothash=$output_rh action=ALLOW
dmverity_signature:
Follow the setup steps for dmverity_roothash. Sign the roothash via:
openssl smime -sign -in "output.roothash" -signer "$MY_CERTIFICATE" \
-inkey "$MY_PRIVATE_KEY" -binary -outform der -noattr \
-out "output.p7s"
Create a policy:
policy_name="verified" policy_version=0.0.0
DEFAULT action=DENY
op=EXECUTE boot_verified=TRUE action=ALLOW
op=EXECUTE dmverity_verified=TRUE action=ALLOW
Deploy the policy, and mark as active, per the "Deploying Policies"
section of this cover letter. Mount the dm-verity volume with
verification:
veritysetup open output.squashfs output.hashtree unverified \
`cat output.roothash` --root-hash-signature=output.p7s
mount /dev/mapper/unverified /my/mount/point
NOTE: The --root-hash-signature option was introduced in veritysetup
2.3.0
Turn on success auditing and attempt to execute a binary in the mount
point, and it should emit an audit event for a match against the rule:
op=EXECUTE dmverity_verified=TRUE action=ALLOW
To test denials, mount the dm-verity volume the same way as the
"dmverity_roothash" section, and attempt to execute a binary. Failure
should occur.
Documentation:
------------------------------------
Full documentation is available on github in IPE's master repository
(Appendix A). This is intended to be an exhaustive source of documentation
around IPE.
Additionally, there is higher level documentation in the admin-guide.
Technical diagrams are available here:
http://microsoft.github.io/ipe/technical/diagrams/
Known Gaps:
------------------------------------
IPE has two known gaps:
1. IPE cannot verify the integrity of anonymous executable memory, such as
the trampolines created by gcc closures and libffi, or JIT'd code.
Unfortunately, as this is dynamically generated code, there is no way for
IPE to detect that this code has not been tampered with in transition
from where it was built, to where it is running. As a result, IPE is
incapable of tackling this problem for dynamically generated code.
However, there is a patch series being prepared that addresses this
problem for libffi and gcc closures by implemeting a safer kernel
trampoline API.
2. IPE cannot verify the integrity of interpreted languages' programs when
these scripts invoked via `<interpreter> <file>`. This is because the way
interpreters execute these files, the scripts themselves are not
evaluated as executable code through one of IPE's hooks. Interpreters
can be enlightened to the usage of IPE by trying to mmap a file into
executable memory (+X), after opening the file and responding to the
error code appropriately. This also applies to included files, or high
value files, such as configuration files of critical system components.
This specific gap is planned on being addressed within IPE. For more
information on how we plan to address this gap, please see the Future
Development section, below.
Future Development:
------------------------------------
Support for filtering signatures by specific certificates. In this case,
our "dmverity_signature" (or a separate property) can be set to a
specific certificate declared in IPE's policy, allowing for more
controlled use-cases determine by a user's PKI structure.
Support for integrity verification for general file reads. This addresses
the script interpreter issue indicated in the "Known Gaps" section, as
these script files are typically opened with O_RDONLY. We are evaluating
whether to do this by comparing the original userland filepath passed into
the open syscall, thereby allowing existing callers to take advantage
without any code changes; the alternate design is to extend the new
openat2(2) syscall, with an new flag, tentatively called "O_VERIFY". While
the second option requires a code change for all the interpreters,
frameworks and languages that wish to leverage it, it is a wholly cleaner
implementation in the kernel. For interpreters specifically, the O_MAYEXEC
patch series published by Mickaël Salaün[1] is a similar implementation
to the O_VERIFY idea described above.
Onboarding IPE's test suite to KernelCI. Currently we are developing a
test suite in the same vein as SELinux's test suite. Once development
of the test suite is complete, and provided IPE is accepted, we intend
to onboard this test suite onto KernelCI.
Hardened resistance against roll-back attacks. Currently there exists a
window of opportunity between user-mode setup and the user-policy being
deployed, where a prior user-policy can be loaded, that is potentially
insecure. However, with a kernel update, you can revise the boot policy's
version to be the same version as the latest policy, closing this window.
In the future, I would like to close this window of opportunity without
a kernel update, using some persistent storage mechanism.
Open Issues:
------------
For linux-audit/integrity folks:
1. Introduction of new audit definitions in the kernel integrity range - is
this preferred, as opposed to reusing definitions with existing IMA
definitions?
TODOs:
------
linux-audit changes to support the new audit events.
Appendix:
------------------------------------
A. IPE Github Repository: https://github.com/microsoft/ipe
Hosted Documentation: https://microsoft.github.io/ipe
B. IPE Users' Guide: Documentation/admin-guide/LSM/ipe.rst
C. IPE Test Suite: *TBA* (under development)
References:
------------------------------------
1. https://lore.kernel.org/linux-integrity/20200505153156.925111-1-mic@digik...
Changelog:
------------------------------------
v1: Introduced
v2:
Split the second patch of the previous series into two.
Minor corrections in the cover-letter and documentation
comments regarding CAP_MAC_ADMIN checks in IPE.
v3:
Address various comments by Jann Horn. Highlights:
Switch various audit allocators to GFP_KERNEL.
Utilize rcu_access_pointer() in various locations.
Strip out the caching system for properties
Strip comments from headers
Move functions around in patches
Remove kernel command line parameters
Reconcile the race condition on the delete node for policy by
expanding the policy critical section.
Address a few comments by Jonathan Corbet around the documentation
pages for IPE.
Fix an issue with the initialization of IPE policy with a "-0"
version, caused by not initializing the hlist entries before
freeing.
v4:
Address a concern around IPE's behavior with unknown syntax.
Specifically, make any unknown syntax a fatal error instead of a
warning, as suggested by Mickaël Salaün.
Introduce a new securityfs node, $securityfs/ipe/property_config,
which provides a listing of what properties are enabled by the
kernel and their versions. This allows usermode to predict what
policies should be allowed.
Strip some comments from c files that I missed.
Clarify some documentation comments around 'boot_verified'.
While this currently does not functionally change the property
itself, the distinction is important when IPE can enforce verified
reads. Additionally, 'KERNEL_READ' was omitted from the documentation.
This has been corrected.
Change SecurityFS and SHA1 to a reverse dependency.
Update the cover-letter with the updated behavior of unknown syntax.
Remove all sysctls, making an equivalent function in securityfs.
Rework the active/delete mechanism to be a node under the policy in
$securityfs/ipe/policies.
The kernel command line parameters ipe.enforce and ipe.success_audit
have returned as this functionality is no longer exposed through
sysfs.
Deven Bowers (12):
scripts: add ipe tooling to generate boot policy
security: add ipe lsm evaluation loop and audit system
security: add ipe lsm policy parser and policy loading
ipe: add property for trust of boot volume
fs: add security blob and hooks for block_device
dm-verity: move signature check after tree validation
dm-verity: add bdev_setsecurity hook for dm-verity signature
ipe: add property for signed dmverity volumes
dm-verity: add bdev_setsecurity hook for root-hash
ipe: add property for dmverity roothash
documentation: add ipe documentation
cleanup: uapi/linux/audit.h
Documentation/admin-guide/LSM/index.rst | 1 +
Documentation/admin-guide/LSM/ipe.rst | 472 +++++++
MAINTAINERS | 8 +
drivers/md/dm-verity-target.c | 50 +-
drivers/md/dm-verity-verify-sig.c | 147 +-
drivers/md/dm-verity-verify-sig.h | 20 +-
drivers/md/dm-verity.h | 2 +-
fs/block_dev.c | 8 +
include/linux/device-mapper.h | 3 +
include/linux/fs.h | 1 +
include/linux/lsm_hook_defs.h | 5 +
include/linux/lsm_hooks.h | 11 +
include/linux/security.h | 22 +
include/uapi/linux/audit.h | 36 +-
scripts/Makefile | 1 +
scripts/ipe/Makefile | 2 +
scripts/ipe/polgen/.gitignore | 1 +
scripts/ipe/polgen/Makefile | 7 +
scripts/ipe/polgen/polgen.c | 136 ++
security/Kconfig | 12 +-
security/Makefile | 2 +
security/ipe/.gitignore | 2 +
security/ipe/Kconfig | 47 +
security/ipe/Makefile | 33 +
security/ipe/ipe-audit.c | 316 +++++
security/ipe/ipe-audit.h | 26 +
security/ipe/ipe-blobs.c | 91 ++
security/ipe/ipe-blobs.h | 18 +
security/ipe/ipe-engine.c | 221 +++
security/ipe/ipe-engine.h | 49 +
security/ipe/ipe-hooks.c | 169 +++
security/ipe/ipe-hooks.h | 70 +
security/ipe/ipe-parse.c | 890 ++++++++++++
security/ipe/ipe-parse.h | 17 +
security/ipe/ipe-pin.c | 93 ++
security/ipe/ipe-pin.h | 36 +
security/ipe/ipe-policy.c | 148 ++
security/ipe/ipe-policy.h | 69 +
security/ipe/ipe-prop-internal.h | 49 +
security/ipe/ipe-property.c | 142 ++
security/ipe/ipe-property.h | 100 ++
security/ipe/ipe-secfs.c | 1316 ++++++++++++++++++
security/ipe/ipe-secfs.h | 16 +
security/ipe/ipe.c | 116 ++
security/ipe/ipe.h | 22 +
security/ipe/properties/Kconfig | 36 +
security/ipe/properties/Makefile | 13 +
security/ipe/properties/boot-verified.c | 82 ++
security/ipe/properties/dmverity-roothash.c | 153 ++
security/ipe/properties/dmverity-signature.c | 82 ++
security/ipe/properties/prop-entry.h | 38 +
security/ipe/utility.h | 32 +
security/security.c | 61 +
53 files changed, 5406 insertions(+), 94 deletions(-)
create mode 100644 Documentation/admin-guide/LSM/ipe.rst
create mode 100644 scripts/ipe/Makefile
create mode 100644 scripts/ipe/polgen/.gitignore
create mode 100644 scripts/ipe/polgen/Makefile
create mode 100644 scripts/ipe/polgen/polgen.c
create mode 100644 security/ipe/.gitignore
create mode 100644 security/ipe/Kconfig
create mode 100644 security/ipe/Makefile
create mode 100644 security/ipe/ipe-audit.c
create mode 100644 security/ipe/ipe-audit.h
create mode 100644 security/ipe/ipe-blobs.c
create mode 100644 security/ipe/ipe-blobs.h
create mode 100644 security/ipe/ipe-engine.c
create mode 100644 security/ipe/ipe-engine.h
create mode 100644 security/ipe/ipe-hooks.c
create mode 100644 security/ipe/ipe-hooks.h
create mode 100644 security/ipe/ipe-parse.c
create mode 100644 security/ipe/ipe-parse.h
create mode 100644 security/ipe/ipe-pin.c
create mode 100644 security/ipe/ipe-pin.h
create mode 100644 security/ipe/ipe-policy.c
create mode 100644 security/ipe/ipe-policy.h
create mode 100644 security/ipe/ipe-prop-internal.h
create mode 100644 security/ipe/ipe-property.c
create mode 100644 security/ipe/ipe-property.h
create mode 100644 security/ipe/ipe-secfs.c
create mode 100644 security/ipe/ipe-secfs.h
create mode 100644 security/ipe/ipe.c
create mode 100644 security/ipe/ipe.h
create mode 100644 security/ipe/properties/Kconfig
create mode 100644 security/ipe/properties/Makefile
create mode 100644 security/ipe/properties/boot-verified.c
create mode 100644 security/ipe/properties/dmverity-roothash.c
create mode 100644 security/ipe/properties/dmverity-signature.c
create mode 100644 security/ipe/properties/prop-entry.h
create mode 100644 security/ipe/utility.h
--
2.27.0
4 years, 3 months
Re: [PATCH] ima: Rename internal audit rule functions
by Mimi Zohar
[Cc'ing the audit mailing list]
On Mon, 2020-06-29 at 10:30 -0500, Tyler Hicks wrote:
>
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index ff2bf57ff0c7..5d62ee8319f4 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -419,24 +419,24 @@ static inline void ima_free_modsig(struct modsig *modsig)
> /* LSM based policy rules require audit */
> #ifdef CONFIG_IMA_LSM_RULES
>
> -#define security_filter_rule_init security_audit_rule_init
> -#define security_filter_rule_free security_audit_rule_free
> -#define security_filter_rule_match security_audit_rule_match
> +#define ima_audit_rule_init security_audit_rule_init
> +#define ima_audit_rule_free security_audit_rule_free
> +#define ima_audit_rule_match security_audit_rule_match
Instead of defining an entirely new method of identifying files, IMA
piggybacks on top of the existing audit rule syntax. IMA policy rules
"filter" based on this information.
IMA already audits security/integrity related events. Using the word
"audit" here will make things even more confusing than they currently
are. Renaming these functions as ima_audit_rule_XXX provides no
benefit. At that point, IMA might as well call the
security_audit_rule prefixed function names directly. As a quick fix,
rename them as "ima_filter_rule".
The correct solution would probably be to rename these prefixed
"security_audit_rule" functions as "security_filter_rule", so that
both the audit subsystem and IMA could use them.
Mimi
4 years, 3 months
[PATCH ghak122 v1] audit: store event sockaddr in case of no rules
by Richard Guy Briggs
When there are no rules present, the event SOCKADDR record is not
generated due to audit_dummy_context() generated at syscall entry from
audit_n_rules. Store this information if there is a context present to
store it so that mandatory events are more complete (startup, LSMs...).
Please see the upstream issue
https://github.com/linux-audit/audit-kernel/issues/122
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Passes audit-testsuite.
include/linux/audit.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 03c4035a532b..07fecd99741a 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -448,7 +448,7 @@ static inline int audit_socketcall_compat(int nargs, u32 *args)
static inline int audit_sockaddr(int len, void *addr)
{
- if (unlikely(!audit_dummy_context()))
+ if (audit_context())
return __audit_sockaddr(len, addr);
return 0;
}
--
1.8.3.1
4 years, 3 months
[PATCH v18 21/23] Audit: Add a new record for multiple object LSM attributes
by Casey Schaufler
Create a new audit record type to contain the object information
when there are multiple security modules that require such data.
This record is emitted before the other records for the event, but
is linked with the same timestamp and serial number.
Reviewed-by: Kees Cook <keescook(a)chromium.org>
Signed-off-by: Casey Schaufler <casey(a)schaufler-ca.com>
Cc: linux-audit(a)redhat.com
---
include/linux/audit.h | 2 ++
include/uapi/linux/audit.h | 1 +
kernel/audit.c | 53 +++++++++++++++++++++++++++++
kernel/audit.h | 4 +--
kernel/auditsc.c | 70 +++++---------------------------------
5 files changed, 67 insertions(+), 63 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 4693febcf41f..3cc02ddd7779 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -171,6 +171,8 @@ extern void audit_log_lost(const char *message);
extern void audit_log_lsm(struct lsmblob *blob, bool exiting);
extern int audit_log_task_context(struct audit_buffer *ab,
struct lsmblob *blob);
+extern int audit_log_object_context(struct audit_buffer *ab,
+ struct lsmblob *blob);
extern void audit_log_task_info(struct audit_buffer *ab);
extern int audit_update_lsm_rules(void);
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index a5403efc2fdf..753a69c6bbbe 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -140,6 +140,7 @@
#define AUDIT_MAC_CALIPSO_ADD 1418 /* NetLabel: add CALIPSO DOI entry */
#define AUDIT_MAC_CALIPSO_DEL 1419 /* NetLabel: del CALIPSO DOI entry */
#define AUDIT_MAC_TASK_CONTEXTS 1420 /* Multiple LSM contexts */
+#define AUDIT_MAC_OBJ_CONTEXTS 1421 /* Multiple LSM object contexts */
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
#define AUDIT_LAST_KERN_ANOM_MSG 1799
diff --git a/kernel/audit.c b/kernel/audit.c
index 9ca8445ca539..e05f9e1f1254 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2177,6 +2177,59 @@ int audit_log_task_context(struct audit_buffer *ab, struct lsmblob *blob)
}
EXPORT_SYMBOL(audit_log_task_context);
+int audit_log_object_context(struct audit_buffer *ab,
+ struct lsmblob *blob)
+{
+ int i;
+ int error;
+ bool sep = false;
+ struct lsmcontext lsmdata;
+ struct audit_buffer *lsmab = NULL;
+ struct audit_context *context = NULL;
+
+ /*
+ * If there is more than one security module that has a
+ * object "context" it's necessary to put the object data
+ * into a separate record to maintain compatibility.
+ */
+ if (security_lsm_slot_name(1) != NULL) {
+ audit_log_format(ab, " obj=?");
+ context = ab->ctx;
+ if (context)
+ lsmab = audit_log_start(context, GFP_KERNEL,
+ AUDIT_MAC_OBJ_CONTEXTS);
+ }
+
+ for (i = 0; i < LSMBLOB_ENTRIES; i++) {
+ if (blob->secid[i] == 0)
+ continue;
+ error = security_secid_to_secctx(blob, &lsmdata, i);
+ if (error && error != -EINVAL) {
+ audit_panic("error in audit_log_object_context");
+ return error;
+ }
+
+ if (context) {
+ audit_log_format(lsmab, "%sobj_%s=%s",
+ sep ? " " : "",
+ security_lsm_slot_name(i),
+ lsmdata.context);
+ sep = true;
+ } else
+ audit_log_format(ab, " obj=%s", lsmdata.context);
+
+ security_release_secctx(&lsmdata);
+ if (!context)
+ break;
+ }
+
+ if (context)
+ audit_log_end(lsmab);
+
+ return 0;
+}
+EXPORT_SYMBOL(audit_log_object_context);
+
void audit_log_d_path_exe(struct audit_buffer *ab,
struct mm_struct *mm)
{
diff --git a/kernel/audit.h b/kernel/audit.h
index 8efb68c21c2d..830e4dfeb83b 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -78,7 +78,7 @@ struct audit_names {
kuid_t uid;
kgid_t gid;
dev_t rdev;
- u32 osid;
+ struct lsmblob oblob;
struct audit_cap_data fcap;
unsigned int fcap_ver;
unsigned char type; /* record type */
@@ -152,7 +152,7 @@ struct audit_context {
kuid_t uid;
kgid_t gid;
umode_t mode;
- u32 osid;
+ struct lsmblob oblob;
int has_perm;
uid_t perm_uid;
gid_t perm_gid;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 54639da63dbf..db8628709971 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -670,14 +670,6 @@ static int audit_filter_rules(struct task_struct *tsk,
if (f->lsm_isset) {
/* Find files that match */
if (name) {
- /*
- * lsmblob_init sets all values in the
- * lsmblob to sid. This is temporary
- * until name->osid is converted to a
- * lsmblob, which happens later in
- * this patch set.
- */
- lsmblob_init(&blob, name->osid);
result = security_audit_rule_match(
&blob,
f->type,
@@ -685,7 +677,6 @@ static int audit_filter_rules(struct task_struct *tsk,
f->lsm_rules);
} else if (ctx) {
list_for_each_entry(n, &ctx->names_list, list) {
- lsmblob_init(&blob, name->osid);
if (security_audit_rule_match(
&blob,
f->type,
@@ -699,8 +690,7 @@ static int audit_filter_rules(struct task_struct *tsk,
/* Find ipc objects that match */
if (!ctx || ctx->type != AUDIT_IPC)
break;
- lsmblob_init(&blob, ctx->ipc.osid);
- if (security_audit_rule_match(&blob,
+ if (security_audit_rule_match(&ctx->ipc.oblob,
f->type, f->op,
f->lsm_rules))
++result;
@@ -982,7 +972,6 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
struct lsmblob *blob, char *comm)
{
struct audit_buffer *ab;
- struct lsmcontext lsmctx;
int rc = 0;
ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
@@ -992,15 +981,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid,
from_kuid(&init_user_ns, auid),
from_kuid(&init_user_ns, uid), sessionid);
- if (lsmblob_is_set(blob)) {
- if (security_secid_to_secctx(blob, &lsmctx, LSMBLOB_FIRST)) {
- audit_log_format(ab, " obj=(none)");
- rc = 1;
- } else {
- audit_log_format(ab, " obj=%s", lsmctx.context);
- security_release_secctx(&lsmctx);
- }
- }
+ rc = audit_log_object_context(ab, blob);
audit_log_format(ab, " ocomm=");
audit_log_untrustedstring(ab, comm);
audit_log_end(ab);
@@ -1227,26 +1208,14 @@ static void show_special(struct audit_context *context, int *call_panic)
context->socketcall.args[i]);
break; }
case AUDIT_IPC: {
- u32 osid = context->ipc.osid;
+ struct lsmblob *oblob = &context->ipc.oblob;
audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
from_kuid(&init_user_ns, context->ipc.uid),
from_kgid(&init_user_ns, context->ipc.gid),
context->ipc.mode);
- if (osid) {
- struct lsmcontext lsmcxt;
- struct lsmblob blob;
-
- lsmblob_init(&blob, osid);
- if (security_secid_to_secctx(&blob, &lsmcxt,
- LSMBLOB_FIRST)) {
- audit_log_format(ab, " osid=%u", osid);
- *call_panic = 1;
- } else {
- audit_log_format(ab, " obj=%s", lsmcxt.context);
- security_release_secctx(&lsmcxt);
- }
- }
+ if (audit_log_object_context(ab, oblob))
+ *call_panic = 1;
if (context->ipc.has_perm) {
audit_log_end(ab);
ab = audit_log_start(context, GFP_KERNEL,
@@ -1386,20 +1355,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
from_kgid(&init_user_ns, n->gid),
MAJOR(n->rdev),
MINOR(n->rdev));
- if (n->osid != 0) {
- struct lsmblob blob;
- struct lsmcontext lsmctx;
-
- lsmblob_init(&blob, n->osid);
- if (security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_FIRST)) {
- audit_log_format(ab, " osid=%u", n->osid);
- if (call_panic)
- *call_panic = 2;
- } else {
- audit_log_format(ab, " obj=%s", lsmctx.context);
- security_release_secctx(&lsmctx);
- }
- }
+ if (audit_log_object_context(ab, &n->oblob) && call_panic)
+ *call_panic = 2;
/* log the audit_names record type */
switch (n->type) {
@@ -1992,17 +1949,13 @@ static void audit_copy_inode(struct audit_names *name,
const struct dentry *dentry,
struct inode *inode, unsigned int flags)
{
- struct lsmblob blob;
-
name->ino = inode->i_ino;
name->dev = inode->i_sb->s_dev;
name->mode = inode->i_mode;
name->uid = inode->i_uid;
name->gid = inode->i_gid;
name->rdev = inode->i_rdev;
- security_inode_getsecid(inode, &blob);
- /* scaffolding until osid is updated */
- name->osid = blob.secid[0];
+ security_inode_getsecid(inode, &name->oblob);
if (flags & AUDIT_INODE_NOEVAL) {
name->fcap_ver = -1;
return;
@@ -2369,16 +2322,11 @@ void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
{
struct audit_context *context = audit_context();
- struct lsmblob blob;
context->ipc.uid = ipcp->uid;
context->ipc.gid = ipcp->gid;
context->ipc.mode = ipcp->mode;
context->ipc.has_perm = 0;
- security_ipc_getsecid(ipcp, &blob);
- /* context->ipc.osid will be changed to a lsmblob later in
- * the patch series. This will allow auditing of all the object
- * labels associated with the ipc object. */
- context->ipc.osid = lsmblob_value(&blob);
+ security_ipc_getsecid(ipcp, &context->ipc.oblob);
context->type = AUDIT_IPC;
}
--
2.24.1
4 years, 3 months
[PATCH v18 20/23] Audit: Add new record for multiple process LSM attributes
by Casey Schaufler
Create a new audit record type to contain the subject information
when there are multiple security modules that require such data.
This record is linked with the same timestamp and serial number.
The record is produced only in cases where there is more than one
security module with a process "context".
Before this change the only audit events that required multiple
records were syscall events. Several non-syscall events include
subject contexts, so the use of audit_context data has been expanded
as necessary.
Signed-off-by: Casey Schaufler <casey(a)schaufler-ca.com>
Cc: linux-audit(a)redhat.com
---
drivers/android/binder.c | 2 +-
include/linux/audit.h | 13 +++-
include/linux/security.h | 9 ++-
include/net/netlabel.h | 2 +-
include/net/scm.h | 3 +-
include/net/xfrm.h | 4 +-
include/uapi/linux/audit.h | 1 +
kernel/audit.c | 90 ++++++++++++++++++-------
kernel/audit.h | 5 ++
kernel/auditfilter.c | 2 +-
kernel/auditsc.c | 87 ++++++++++++++++++++++--
net/ipv4/ip_sockglue.c | 2 +-
net/netfilter/nf_conntrack_netlink.c | 4 +-
net/netfilter/nf_conntrack_standalone.c | 2 +-
net/netfilter/nfnetlink_queue.c | 2 +-
net/netlabel/netlabel_unlabeled.c | 16 ++---
net/netlabel/netlabel_user.c | 12 ++--
net/netlabel/netlabel_user.h | 6 +-
security/integrity/integrity_audit.c | 2 +-
security/security.c | 71 ++++++++++++++-----
security/smack/smackfs.c | 3 +-
21 files changed, 255 insertions(+), 83 deletions(-)
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index ceb5987c7d76..99b1e65b193c 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3109,7 +3109,7 @@ static void binder_transaction(struct binder_proc *proc,
size_t added_size;
security_task_getsecid(proc->tsk, &blob);
- ret = security_secid_to_secctx(&blob, &lsmctx);
+ ret = security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_DISPLAY);
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;
diff --git a/include/linux/audit.h b/include/linux/audit.h
index aabbbe6d9296..4693febcf41f 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -168,7 +168,9 @@ extern void audit_log_path_denied(int type,
const char *operation);
extern void audit_log_lost(const char *message);
-extern int audit_log_task_context(struct audit_buffer *ab);
+extern void audit_log_lsm(struct lsmblob *blob, bool exiting);
+extern int audit_log_task_context(struct audit_buffer *ab,
+ struct lsmblob *blob);
extern void audit_log_task_info(struct audit_buffer *ab);
extern int audit_update_lsm_rules(void);
@@ -228,7 +230,10 @@ static inline void audit_log_key(struct audit_buffer *ab, char *key)
{ }
static inline void audit_log_path_denied(int type, const char *operation)
{ }
-static inline int audit_log_task_context(struct audit_buffer *ab)
+static inline void audit_log_lsm(struct lsmblob *blob, bool exiting)
+{ }
+static inline int audit_log_task_context(struct audit_buffer *ab,
+ struct lsmblob *blob);
{
return 0;
}
@@ -287,6 +292,7 @@ extern void audit_seccomp(unsigned long syscall, long signr, int code);
extern void audit_seccomp_actions_logged(const char *names,
const char *old_names, int res);
extern void __audit_ptrace(struct task_struct *t);
+extern void audit_stamp_context(struct audit_context *ctx);
static inline void audit_set_context(struct task_struct *task, struct audit_context *ctx)
{
@@ -665,6 +671,9 @@ static inline void audit_ntp_log(const struct audit_ntp_data *ad)
static inline void audit_ptrace(struct task_struct *t)
{ }
+static inline void audit_stamp_context(struct audit_context *ctx)
+{ }
+
static inline void audit_log_nfcfg(const char *name, u8 af,
unsigned int nentries,
enum audit_nfcfgop op)
diff --git a/include/linux/security.h b/include/linux/security.h
index 02dc3b5ef57b..ab62f9040e19 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -179,6 +179,8 @@ struct lsmblob {
#define LSMBLOB_INVALID -1 /* Not a valid LSM slot number */
#define LSMBLOB_NEEDED -2 /* Slot requested on initialization */
#define LSMBLOB_NOT_NEEDED -3 /* Slot not requested */
+#define LSMBLOB_DISPLAY -4 /* Use the "display" slot */
+#define LSMBLOB_FIRST -5 /* Use the default "display" slot */
/**
* lsmblob_init - initialize an lsmblob structure.
@@ -241,6 +243,8 @@ static inline u32 lsmblob_value(const struct lsmblob *blob)
return 0;
}
+const char *security_lsm_slot_name(int slot);
+
/* These functions are in security/commoncap.c */
extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
int cap, unsigned int opts);
@@ -553,7 +557,8 @@ int security_setprocattr(const char *lsm, const char *name, void *value,
size_t size);
int security_netlink_send(struct sock *sk, struct sk_buff *skb);
int security_ismaclabel(const char *name);
-int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp);
+int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp,
+ int display);
int security_secctx_to_secid(const char *secdata, u32 seclen,
struct lsmblob *blob);
void security_release_secctx(struct lsmcontext *cp);
@@ -1371,7 +1376,7 @@ static inline int security_ismaclabel(const char *name)
}
static inline int security_secid_to_secctx(struct lsmblob *blob,
- struct lsmcontext *cp)
+ struct lsmcontext *cp, int display)
{
return -EOPNOTSUPP;
}
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 73fc25b4042b..216cb1ffc8f0 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -97,7 +97,7 @@ struct calipso_doi;
/* NetLabel audit information */
struct netlbl_audit {
- u32 secid;
+ struct lsmblob lsmdata;
kuid_t loginuid;
unsigned int sessionid;
};
diff --git a/include/net/scm.h b/include/net/scm.h
index 4a6ad8caf423..8b5a4737e1b8 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -96,7 +96,8 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
int err;
if (test_bit(SOCK_PASSSEC, &sock->flags)) {
- err = security_secid_to_secctx(&scm->lsmblob, &context);
+ err = security_secid_to_secctx(&scm->lsmblob, &context,
+ LSMBLOB_DISPLAY);
if (!err) {
put_cmsg(msg, SOL_SOCKET, SCM_SECURITY,
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index c7d213c9f9d8..930432c3912e 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -672,11 +672,13 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op)
if (audit_enabled == AUDIT_OFF)
return NULL;
+ audit_stamp_context(audit_context());
audit_buf = audit_log_start(audit_context(), GFP_ATOMIC,
AUDIT_MAC_IPSEC_EVENT);
if (audit_buf == NULL)
return NULL;
audit_log_format(audit_buf, "op=%s", op);
+ audit_log_lsm(NULL, false);
return audit_buf;
}
@@ -690,7 +692,7 @@ static inline void xfrm_audit_helper_usrinfo(bool task_valid,
AUDIT_SID_UNSET;
audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
- audit_log_task_context(audit_buf);
+ audit_log_task_context(audit_buf, NULL);
}
void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid);
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 9b6a973f4cc3..a5403efc2fdf 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -139,6 +139,7 @@
#define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */
#define AUDIT_MAC_CALIPSO_ADD 1418 /* NetLabel: add CALIPSO DOI entry */
#define AUDIT_MAC_CALIPSO_DEL 1419 /* NetLabel: del CALIPSO DOI entry */
+#define AUDIT_MAC_TASK_CONTEXTS 1420 /* Multiple LSM contexts */
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
#define AUDIT_LAST_KERN_ANOM_MSG 1799
diff --git a/kernel/audit.c b/kernel/audit.c
index d300e41ca443..9ca8445ca539 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -389,10 +389,11 @@ static int audit_log_config_change(char *function_name, u32 new, u32 old,
return rc;
audit_log_format(ab, "op=set %s=%u old=%u ", function_name, new, old);
audit_log_session_info(ab);
- rc = audit_log_task_context(ab);
+ rc = audit_log_task_context(ab, NULL);
if (rc)
allow_changes = 0; /* Something weird, deny request */
audit_log_format(ab, " res=%d", allow_changes);
+ audit_log_lsm(NULL, false);
audit_log_end(ab);
return rc;
}
@@ -1065,13 +1066,31 @@ static void audit_log_common_recv_msg(struct audit_context *context,
return;
audit_log_format(*ab, "pid=%d uid=%u ", pid, uid);
audit_log_session_info(*ab);
- audit_log_task_context(*ab);
+ audit_log_task_context(*ab, NULL);
}
static inline void audit_log_user_recv_msg(struct audit_buffer **ab,
u16 msg_type)
{
- audit_log_common_recv_msg(NULL, ab, msg_type);
+ struct audit_context *context;
+
+ if (!audit_lsm_multiple_contexts()) {
+ audit_log_common_recv_msg(NULL, ab, msg_type);
+ return;
+ }
+
+ context = audit_context();
+ if (context) {
+ if (!context->in_syscall)
+ audit_stamp_context(context);
+ audit_log_common_recv_msg(context, ab, msg_type);
+ return;
+ }
+
+ audit_alloc(current);
+ context = audit_context();
+
+ audit_log_common_recv_msg(context, ab, msg_type);
}
int is_audit_feature_set(int i)
@@ -1361,6 +1380,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
audit_log_n_untrustedstring(ab, str, data_len);
}
audit_log_end(ab);
+ audit_log_lsm(NULL, false);
}
break;
case AUDIT_ADD_RULE:
@@ -1430,7 +1450,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case AUDIT_SIGNAL_INFO:
if (lsmblob_is_set(&audit_sig_lsm)) {
err = security_secid_to_secctx(&audit_sig_lsm,
- &context);
+ &context, LSMBLOB_FIRST);
if (err)
return err;
}
@@ -1556,7 +1576,7 @@ static void audit_log_multicast(int group, const char *op, int err)
tty ? tty_name(tty) : "(none)",
audit_get_sessionid(current));
audit_put_tty(tty);
- audit_log_task_context(ab); /* subj= */
+ audit_log_task_context(ab, NULL); /* subj= */
audit_log_format(ab, " comm=");
audit_log_untrustedstring(ab, get_task_comm(comm, current));
audit_log_d_path_exe(ab, current->mm); /* exe= */
@@ -1851,6 +1871,11 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
audit_get_stamp(ab->ctx, &t, &serial);
audit_clear_dummy(ab->ctx);
+
+ if (type == AUDIT_MAC_TASK_CONTEXTS && ab->ctx->serial == 0) {
+ audit_stamp_context(ab->ctx);
+ audit_get_stamp(ab->ctx, &t, &serial);
+ }
audit_log_format(ab, "audit(%llu.%03lu:%u): ",
(unsigned long long)t.tv_sec, t.tv_nsec/1000000, serial);
@@ -2108,30 +2133,47 @@ void audit_log_key(struct audit_buffer *ab, char *key)
audit_log_format(ab, "(null)");
}
-int audit_log_task_context(struct audit_buffer *ab)
+int audit_log_task_context(struct audit_buffer *ab, struct lsmblob *blob)
{
+ int i;
int error;
- struct lsmblob blob;
- struct lsmcontext context;
+ struct lsmblob localblob;
+ struct lsmcontext lsmdata;
- security_task_getsecid(current, &blob);
- if (!lsmblob_is_set(&blob))
+ /*
+ * If there is more than one security module that has a
+ * subject "context" it's necessary to put the subject data
+ * into a separate record to maintain compatibility.
+ */
+ if (audit_lsm_multiple_contexts()) {
+ audit_log_format(ab, " subj=?");
return 0;
+ }
- error = security_secid_to_secctx(&blob, &context);
- if (error) {
- if (error != -EINVAL)
- goto error_path;
- return 0;
+ if (blob == NULL) {
+ security_task_getsecid(current, &localblob);
+ if (!lsmblob_is_set(&localblob)) {
+ audit_log_format(ab, " subj=?");
+ return 0;
+ }
+ blob = &localblob;
}
- audit_log_format(ab, " subj=%s", context.context);
- security_release_secctx(&context);
- return 0;
+ for (i = 0; i < LSMBLOB_ENTRIES; i++) {
+ if (blob->secid[i] == 0)
+ continue;
+ error = security_secid_to_secctx(blob, &lsmdata, i);
+ if (error && error != -EINVAL) {
+ audit_panic("error in audit_log_task_context");
+ return error;
+ }
+
+ audit_log_format(ab, " subj=%s", lsmdata.context);
+ security_release_secctx(&lsmdata);
+ break;
+ }
-error_path:
- audit_panic("error in audit_log_task_context");
- return error;
+ return 0;
}
EXPORT_SYMBOL(audit_log_task_context);
@@ -2203,7 +2245,7 @@ void audit_log_task_info(struct audit_buffer *ab)
audit_log_format(ab, " comm=");
audit_log_untrustedstring(ab, get_task_comm(comm, current));
audit_log_d_path_exe(ab, current->mm);
- audit_log_task_context(ab);
+ audit_log_task_context(ab, NULL);
}
EXPORT_SYMBOL(audit_log_task_info);
@@ -2261,6 +2303,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
if (!audit_enabled)
return;
+ audit_stamp_context(audit_context());
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_LOGIN);
if (!ab)
return;
@@ -2271,11 +2314,12 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
tty = audit_get_tty();
audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid);
- audit_log_task_context(ab);
+ audit_log_task_context(ab, NULL);
audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d",
oldloginuid, loginuid, tty ? tty_name(tty) : "(none)",
oldsessionid, sessionid, !rc);
audit_put_tty(tty);
+ audit_log_lsm(NULL, true);
audit_log_end(ab);
}
diff --git a/kernel/audit.h b/kernel/audit.h
index 6ab012e5fe98..8efb68c21c2d 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -298,6 +298,11 @@ static inline void audit_clear_dummy(struct audit_context *ctx)
ctx->dummy = 0;
}
+static inline bool audit_lsm_multiple_contexts(void)
+{
+ return security_lsm_slot_name(1) != NULL;
+}
+
#else /* CONFIG_AUDITSYSCALL */
#define auditsc_get_stamp(c, t, s) 0
#define audit_put_watch(w) {}
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 31732023b689..6c03e463668e 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1107,7 +1107,7 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re
if (!ab)
return;
audit_log_session_info(ab);
- audit_log_task_context(ab);
+ audit_log_task_context(ab, NULL);
audit_log_format(ab, " op=%s", action);
audit_log_key(ab, rule->filterkey);
audit_log_format(ab, " list=%d res=%d", rule->listnr, res);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 1f7bd6b34ec7..54639da63dbf 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -455,7 +455,7 @@ static int audit_filter_rules(struct task_struct *tsk,
{
const struct cred *cred;
int i, need_sid = 1;
- struct lsmblob blob;
+ struct lsmblob blob = { };
unsigned int sessionid;
cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation);
@@ -944,10 +944,12 @@ int audit_alloc(struct task_struct *tsk)
return 0; /* Return if not auditing. */
state = audit_filter_task(tsk, &key);
- if (state == AUDIT_DISABLED) {
+ if (!audit_lsm_multiple_contexts() && state == AUDIT_DISABLED) {
clear_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
return 0;
}
+ if (state == AUDIT_DISABLED)
+ clear_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
if (!(context = audit_alloc_context(state))) {
kfree(key);
@@ -991,7 +993,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
from_kuid(&init_user_ns, auid),
from_kuid(&init_user_ns, uid), sessionid);
if (lsmblob_is_set(blob)) {
- if (security_secid_to_secctx(blob, &lsmctx)) {
+ if (security_secid_to_secctx(blob, &lsmctx, LSMBLOB_FIRST)) {
audit_log_format(ab, " obj=(none)");
rc = 1;
} else {
@@ -1236,7 +1238,8 @@ static void show_special(struct audit_context *context, int *call_panic)
struct lsmblob blob;
lsmblob_init(&blob, osid);
- if (security_secid_to_secctx(&blob, &lsmcxt)) {
+ if (security_secid_to_secctx(&blob, &lsmcxt,
+ LSMBLOB_FIRST)) {
audit_log_format(ab, " osid=%u", osid);
*call_panic = 1;
} else {
@@ -1388,7 +1391,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
struct lsmcontext lsmctx;
lsmblob_init(&blob, n->osid);
- if (security_secid_to_secctx(&blob, &lsmctx)) {
+ if (security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_FIRST)) {
audit_log_format(ab, " osid=%u", n->osid);
if (call_panic)
*call_panic = 2;
@@ -1462,6 +1465,52 @@ static void audit_log_proctitle(void)
audit_log_end(ab);
}
+void audit_log_lsm(struct lsmblob *blob, bool exiting)
+{
+ struct audit_context *context = audit_context();
+ struct lsmcontext lsmdata;
+ struct audit_buffer *ab;
+ struct lsmblob localblob;
+ bool sep = false;
+ int error;
+ int i;
+
+ if (!audit_lsm_multiple_contexts())
+ return;
+
+ if (context && context->in_syscall && !exiting)
+ return;
+
+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_MAC_TASK_CONTEXTS);
+ if (!ab)
+ return; /* audit_panic or being filtered */
+
+ if (blob == NULL) {
+ security_task_getsecid(current, &localblob);
+ if (!lsmblob_is_set(&localblob))
+ return;
+ blob = &localblob;
+ }
+
+ for (i = 0; i < LSMBLOB_ENTRIES; i++) {
+ if (blob->secid[i] == 0)
+ continue;
+ error = security_secid_to_secctx(blob, &lsmdata, i);
+ if (error && error != -EINVAL) {
+ audit_panic("error in audit_log_lsm");
+ return;
+ }
+
+ audit_log_format(ab, "%ssubj_%s=%s", sep ? " " : "",
+ security_lsm_slot_name(i), lsmdata.context);
+ sep = true;
+
+ security_release_secctx(&lsmdata);
+ }
+
+ audit_log_end(ab);
+}
+
static void audit_log_exit(void)
{
int i, call_panic = 0;
@@ -1585,6 +1634,7 @@ static void audit_log_exit(void)
}
audit_log_proctitle();
+ audit_log_lsm(NULL, true);
/* Send end of event record to help user space know we are finished */
ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
@@ -2183,6 +2233,21 @@ void __audit_inode_child(struct inode *parent,
}
EXPORT_SYMBOL_GPL(__audit_inode_child);
+/**
+ * audit_stamp_context - set the timestamp+serial in an audit context
+ * @ctx: audit_context to set
+ */
+void audit_stamp_context(struct audit_context *ctx)
+{
+ /* ctx will be NULL unless audit_lsm_multiple_contexts() is true */
+ if (!ctx)
+ return;
+
+ ktime_get_coarse_real_ts64(&ctx->ctime);
+ ctx->serial = audit_serial();
+ ctx->current_state = AUDIT_BUILD_CONTEXT;
+}
+
/**
* auditsc_get_stamp - get local copies of audit_context values
* @ctx: audit_context for the task
@@ -2194,6 +2259,12 @@ EXPORT_SYMBOL_GPL(__audit_inode_child);
int auditsc_get_stamp(struct audit_context *ctx,
struct timespec64 *t, unsigned int *serial)
{
+ if (ctx->serial && !ctx->in_syscall) {
+ t->tv_sec = ctx->ctime.tv_sec;
+ t->tv_nsec = ctx->ctime.tv_nsec;
+ *serial = ctx->serial;
+ return 1;
+ }
if (!ctx->in_syscall)
return 0;
if (!ctx->serial)
@@ -2588,7 +2659,7 @@ void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
name, af, nentries, audit_nfcfgs[op].s);
audit_log_format(ab, " pid=%u", task_pid_nr(current));
- audit_log_task_context(ab); /* subj= */
+ audit_log_task_context(ab, NULL); /* subj= */
audit_log_format(ab, " comm=");
audit_log_untrustedstring(ab, get_task_comm(comm, current));
audit_log_end(ab);
@@ -2611,7 +2682,7 @@ static void audit_log_task(struct audit_buffer *ab)
from_kuid(&init_user_ns, uid),
from_kgid(&init_user_ns, gid),
sessionid);
- audit_log_task_context(ab);
+ audit_log_task_context(ab, NULL);
audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
audit_log_untrustedstring(ab, get_task_comm(comm, current));
audit_log_d_path_exe(ab, current->mm);
@@ -2634,11 +2705,13 @@ void audit_core_dumps(long signr)
if (signr == SIGQUIT) /* don't care for those */
return;
+ audit_stamp_context(audit_context());
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_ANOM_ABEND);
if (unlikely(!ab))
return;
audit_log_task(ab);
audit_log_format(ab, " sig=%ld res=1", signr);
+ audit_log_lsm(NULL, true);
audit_log_end(ab);
}
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 176ac9ce6069..e5c7a1b94ca4 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -138,7 +138,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
if (err)
return;
- err = security_secid_to_secctx(&lb, &context);
+ err = security_secid_to_secctx(&lb, &context, LSMBLOB_DISPLAY);
if (err)
return;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index e38b5182e301..3c90b9a488d5 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -339,7 +339,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
* security_secid_to_secctx() will know which security module
* to use to create the secctx. */
lsmblob_init(&blob, ct->secmark);
- ret = security_secid_to_secctx(&blob, &context);
+ ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY);
if (ret)
return 0;
@@ -655,7 +655,7 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct)
struct lsmblob blob;
struct lsmcontext context;
- ret = security_secid_to_secctx(&blob, &context);
+ ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY);
if (ret)
return 0;
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 0ecd1040f4f1..de85317a366e 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -177,7 +177,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
struct lsmcontext context;
lsmblob_init(&blob, ct->secmark);
- ret = security_secid_to_secctx(&blob, &context);
+ ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY);
if (ret)
return;
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index a4d4602ab9b7..15cabd7be92a 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -316,7 +316,7 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context)
* blob. security_secid_to_secctx() will know which security
* module to use to create the secctx. */
lsmblob_init(&blob, skb->secmark);
- security_secid_to_secctx(&blob, context);
+ security_secid_to_secctx(&blob, context, LSMBLOB_DISPLAY);
}
read_unlock_bh(&skb->sk->sk_callback_lock);
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index c14a485ff045..99579fa49293 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -437,7 +437,8 @@ int netlbl_unlhsh_add(struct net *net,
unlhsh_add_return:
rcu_read_unlock();
if (audit_buf != NULL) {
- if (security_secid_to_secctx(lsmblob, &context) == 0) {
+ if (security_secid_to_secctx(lsmblob, &context,
+ LSMBLOB_FIRST) == 0) {
audit_log_format(audit_buf, " sec_obj=%s",
context.context);
security_release_secctx(&context);
@@ -492,7 +493,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
if (dev != NULL)
dev_put(dev);
if (entry != NULL &&
- security_secid_to_secctx(&entry->lsmblob, &context) == 0) {
+ security_secid_to_secctx(&entry->lsmblob, &context,
+ LSMBLOB_FIRST) == 0) {
audit_log_format(audit_buf, " sec_obj=%s",
context.context);
security_release_secctx(&context);
@@ -552,7 +554,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
if (dev != NULL)
dev_put(dev);
if (entry != NULL &&
- security_secid_to_secctx(&entry->lsmblob, &context) == 0) {
+ security_secid_to_secctx(&entry->lsmblob, &context,
+ LSMBLOB_FIRST) == 0) {
audit_log_format(audit_buf, " sec_obj=%s",
context.context);
security_release_secctx(&context);
@@ -1122,7 +1125,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
lsmb = (struct lsmblob *)&addr6->lsmblob;
}
- ret_val = security_secid_to_secctx(lsmb, &context);
+ ret_val = security_secid_to_secctx(lsmb, &context, LSMBLOB_FIRST);
if (ret_val != 0)
goto list_cb_failure;
ret_val = nla_put(cb_arg->skb,
@@ -1521,14 +1524,11 @@ int __init netlbl_unlabel_defconf(void)
int ret_val;
struct netlbl_dom_map *entry;
struct netlbl_audit audit_info;
- struct lsmblob blob;
/* Only the kernel is allowed to call this function and the only time
* it is called is at bootup before the audit subsystem is reporting
* messages so don't worry to much about these values. */
- security_task_getsecid(current, &blob);
- /* scaffolding until audit_info.secid is converted */
- audit_info.secid = blob.secid[0];
+ security_task_getsecid(current, &audit_info.lsmdata);
audit_info.loginuid = GLOBAL_ROOT_UID;
audit_info.sessionid = 0;
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 951ba0639d20..4e9064754b5f 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -84,12 +84,12 @@ struct audit_buffer *netlbl_audit_start_common(int type,
struct netlbl_audit *audit_info)
{
struct audit_buffer *audit_buf;
- struct lsmcontext context;
- struct lsmblob blob;
if (audit_enabled == AUDIT_OFF)
return NULL;
+ audit_stamp_context(audit_context());
+
audit_buf = audit_log_start(audit_context(), GFP_ATOMIC, type);
if (audit_buf == NULL)
return NULL;
@@ -98,12 +98,8 @@ struct audit_buffer *netlbl_audit_start_common(int type,
from_kuid(&init_user_ns, audit_info->loginuid),
audit_info->sessionid);
- lsmblob_init(&blob, audit_info->secid);
- if (audit_info->secid != 0 &&
- security_secid_to_secctx(&blob, &context) == 0) {
- audit_log_format(audit_buf, " subj=%s", context.context);
- security_release_secctx(&context);
- }
+ audit_log_task_context(audit_buf, &audit_info->lsmdata);
+ audit_log_lsm(&audit_info->lsmdata, false);
return audit_buf;
}
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h
index 438b5db6c714..bd4335443b87 100644
--- a/net/netlabel/netlabel_user.h
+++ b/net/netlabel/netlabel_user.h
@@ -34,11 +34,7 @@
static inline void netlbl_netlink_auditinfo(struct sk_buff *skb,
struct netlbl_audit *audit_info)
{
- struct lsmblob blob;
-
- security_task_getsecid(current, &blob);
- /* scaffolding until secid is converted */
- audit_info->secid = blob.secid[0];
+ security_task_getsecid(current, &audit_info->lsmdata);
audit_info->loginuid = audit_get_loginuid(current);
audit_info->sessionid = audit_get_sessionid(current);
}
diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c
index 5109173839cc..00d8aa358651 100644
--- a/security/integrity/integrity_audit.c
+++ b/security/integrity/integrity_audit.c
@@ -41,7 +41,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
from_kuid(&init_user_ns, current_cred()->uid),
from_kuid(&init_user_ns, audit_get_loginuid(current)),
audit_get_sessionid(current));
- audit_log_task_context(ab);
+ audit_log_task_context(ab, NULL);
audit_log_format(ab, " op=%s cause=%s comm=", op, cause);
audit_log_untrustedstring(ab, get_task_comm(name, current));
if (fname) {
diff --git a/security/security.c b/security/security.c
index c3fa4b7e9338..2b729d8c94b4 100644
--- a/security/security.c
+++ b/security/security.c
@@ -480,7 +480,31 @@ static int lsm_append(const char *new, char **result)
* Pointers to the LSM id structures for local use.
*/
static int lsm_slot __lsm_ro_after_init;
-static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES];
+static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES] __lsm_ro_after_init;
+
+/**
+ * security_lsm_slot_name - Get the name of the security module in a slot
+ * @slot: index into the "display" slot list.
+ *
+ * Provide the name of the security module associated with
+ * a display slot.
+ *
+ * If @slot is LSMBLOB_INVALID return the value
+ * for slot 0 if it has been set, otherwise NULL.
+ *
+ * Returns a pointer to the name string or NULL.
+ */
+const char *security_lsm_slot_name(int slot)
+{
+ if (slot == LSMBLOB_INVALID)
+ slot = 0;
+ else if (slot >= LSMBLOB_ENTRIES || slot < 0)
+ return NULL;
+
+ if (lsm_slotlist[slot] == NULL)
+ return NULL;
+ return lsm_slotlist[slot]->lsm;
+}
/**
* security_add_hooks - Add a modules hooks to the hook lists.
@@ -2205,13 +2229,32 @@ int security_ismaclabel(const char *name)
}
EXPORT_SYMBOL(security_ismaclabel);
-int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp)
+int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp,
+ int display)
{
struct security_hook_list *hp;
- int display = lsm_task_display(current);
memset(cp, 0, sizeof(*cp));
+ /*
+ * display either is the slot number use for formatting
+ * or an instruction on which relative slot to use.
+ */
+ if (display == LSMBLOB_DISPLAY)
+ display = lsm_task_display(current);
+ else if (display == LSMBLOB_FIRST)
+ display = LSMBLOB_INVALID;
+ else if (display < 0) {
+ WARN_ONCE(true,
+ "LSM: %s unknown display\n", __func__);
+ display = LSMBLOB_INVALID;
+ } else if (display >= lsm_slot) {
+ WARN_ONCE(true,
+ "LSM: %s invalid display\n", __func__);
+ display = LSMBLOB_INVALID;
+ }
+
+
hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) {
if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot))
continue;
@@ -2241,7 +2284,7 @@ int security_secctx_to_secid(const char *secdata, u32 seclen,
return hp->hook.secctx_to_secid(secdata, seclen,
&blob->secid[hp->lsmid->slot]);
}
- return 0;
+ return -EOPNOTSUPP;
}
EXPORT_SYMBOL(security_secctx_to_secid);
@@ -2742,23 +2785,17 @@ int security_key_getsecurity(struct key *key, char **_buffer)
int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule)
{
struct security_hook_list *hp;
- bool one_is_good = false;
- int rc = 0;
- int trc;
+ int display = lsm_task_display(current);
hlist_for_each_entry(hp, &security_hook_heads.audit_rule_init, list) {
if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot))
continue;
- trc = hp->hook.audit_rule_init(field, op, rulestr,
- &lsmrule[hp->lsmid->slot]);
- if (trc == 0)
- one_is_good = true;
- else
- rc = trc;
+ if (display != LSMBLOB_INVALID && display != hp->lsmid->slot)
+ continue;
+ return hp->hook.audit_rule_init(field, op, rulestr,
+ &lsmrule[hp->lsmid->slot]);
}
- if (one_is_good)
- return 0;
- return rc;
+ return 0;
}
int security_audit_rule_known(struct audit_krule *krule)
@@ -2790,6 +2827,8 @@ int security_audit_rule_match(struct lsmblob *blob, u32 field, u32 op,
continue;
if (lsmrule[hp->lsmid->slot] == NULL)
continue;
+ if (lsmrule[hp->lsmid->slot] == NULL)
+ continue;
rc = hp->hook.audit_rule_match(blob->secid[hp->lsmid->slot],
field, op,
&lsmrule[hp->lsmid->slot]);
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 177e69b43a52..2abdb45b3a61 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -185,7 +185,8 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
nap->loginuid = audit_get_loginuid(current);
nap->sessionid = audit_get_sessionid(current);
- nap->secid = skp->smk_secid;
+ lsmblob_init(&nap->lsmdata, 0);
+ nap->lsmdata.secid[smack_lsmid.slot] = skp->smk_secid;
}
/*
--
2.24.1
4 years, 3 months
[PATCH ghak84 v3] audit: purge audit_log_string from the intra-kernel audit API
by Richard Guy Briggs
audit_log_string() was inteded to be an internal audit function and
since there are only two internal uses, remove them. Purge all external
uses of it by restructuring code to use an existing audit_log_format()
or using audit_log_format().
Please see the upstream issue
https://github.com/linux-audit/audit-kernel/issues/84
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Passes audit-testsuite.
Changelog:
v3
- fix two warning: non-void function does not return a value in all control paths
Reported-by: kernel test robot <lkp(a)intel.com>
v2
- restructure to piggyback on existing audit_log_format() calls, checking quoting needs for each.
v1 Vlad Dronov
- https://github.com/nefigtut/audit-kernel/commit/dbbcba46335a002f44b058741...
include/linux/audit.h | 5 -----
kernel/audit.c | 4 ++--
security/apparmor/audit.c | 10 ++++------
security/apparmor/file.c | 25 +++++++------------------
security/apparmor/ipc.c | 46 +++++++++++++++++++++++-----------------------
security/apparmor/net.c | 14 ++++++++------
security/lsm_audit.c | 4 ++--
7 files changed, 46 insertions(+), 62 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 604ede630580..5ad7cd65d76f 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -695,9 +695,4 @@ static inline bool audit_loginuid_set(struct task_struct *tsk)
return uid_valid(audit_get_loginuid(tsk));
}
-static inline void audit_log_string(struct audit_buffer *ab, const char *buf)
-{
- audit_log_n_string(ab, buf, strlen(buf));
-}
-
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index 8c201f414226..a2f3e34aa724 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2080,13 +2080,13 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
/* We will allow 11 spaces for ' (deleted)' to be appended */
pathname = kmalloc(PATH_MAX+11, ab->gfp_mask);
if (!pathname) {
- audit_log_string(ab, "<no_memory>");
+ audit_log_format(ab, "\"<no_memory>\"");
return;
}
p = d_path(path, pathname, PATH_MAX+11);
if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
/* FIXME: can we save some information here? */
- audit_log_string(ab, "<too_long>");
+ audit_log_format(ab, "\"<too_long>\"");
} else
audit_log_untrustedstring(ab, p);
kfree(pathname);
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 597732503815..335b5b8d300b 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -57,18 +57,16 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
struct common_audit_data *sa = ca;
if (aa_g_audit_header) {
- audit_log_format(ab, "apparmor=");
- audit_log_string(ab, aa_audit_type[aad(sa)->type]);
+ audit_log_format(ab, "apparmor=%s",
+ aa_audit_type[aad(sa)->type]);
}
if (aad(sa)->op) {
- audit_log_format(ab, " operation=");
- audit_log_string(ab, aad(sa)->op);
+ audit_log_format(ab, " operation=%s", aad(sa)->op);
}
if (aad(sa)->info) {
- audit_log_format(ab, " info=");
- audit_log_string(ab, aad(sa)->info);
+ audit_log_format(ab, " info=\"%s\"", aad(sa)->info);
if (aad(sa)->error)
audit_log_format(ab, " error=%d", aad(sa)->error);
}
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 9a2d14b7c9f8..70f27124d051 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -35,20 +35,6 @@ static u32 map_mask_to_chr_mask(u32 mask)
}
/**
- * audit_file_mask - convert mask to permission string
- * @buffer: buffer to write string to (NOT NULL)
- * @mask: permission mask to convert
- */
-static void audit_file_mask(struct audit_buffer *ab, u32 mask)
-{
- char str[10];
-
- aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
- map_mask_to_chr_mask(mask));
- audit_log_string(ab, str);
-}
-
-/**
* file_audit_cb - call back for file specific audit fields
* @ab: audit_buffer (NOT NULL)
* @va: audit struct to audit values of (NOT NULL)
@@ -57,14 +43,17 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
{
struct common_audit_data *sa = va;
kuid_t fsuid = current_fsuid();
+ char str[10];
if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " requested_mask=");
- audit_file_mask(ab, aad(sa)->request);
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+ map_mask_to_chr_mask(aad(sa)->request));
+ audit_log_format(ab, " requested_mask=%s", str);
}
if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " denied_mask=");
- audit_file_mask(ab, aad(sa)->denied);
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+ map_mask_to_chr_mask(aad(sa)->denied));
+ audit_log_format(ab, " denied_mask=%s", str);
}
if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
audit_log_format(ab, " fsuid=%d",
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index 4ecedffbdd33..fe431731883f 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -20,25 +20,23 @@
/**
* audit_ptrace_mask - convert mask to permission string
- * @buffer: buffer to write string to (NOT NULL)
* @mask: permission mask to convert
+ *
+ * Returns: pointer to static string
*/
-static void audit_ptrace_mask(struct audit_buffer *ab, u32 mask)
+static const char *audit_ptrace_mask(u32 mask)
{
switch (mask) {
case MAY_READ:
- audit_log_string(ab, "read");
- break;
+ return "read";
case MAY_WRITE:
- audit_log_string(ab, "trace");
- break;
+ return "trace";
case AA_MAY_BE_READ:
- audit_log_string(ab, "readby");
- break;
+ return "readby";
case AA_MAY_BE_TRACED:
- audit_log_string(ab, "tracedby");
- break;
+ return "tracedby";
}
+ return "";
}
/* call back to audit ptrace fields */
@@ -47,12 +45,12 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
struct common_audit_data *sa = va;
if (aad(sa)->request & AA_PTRACE_PERM_MASK) {
- audit_log_format(ab, " requested_mask=");
- audit_ptrace_mask(ab, aad(sa)->request);
+ audit_log_format(ab, " requested_mask=%s",
+ audit_ptrace_mask(aad(sa)->request));
if (aad(sa)->denied & AA_PTRACE_PERM_MASK) {
- audit_log_format(ab, " denied_mask=");
- audit_ptrace_mask(ab, aad(sa)->denied);
+ audit_log_format(ab, " denied_mask=%s",
+ audit_ptrace_mask(aad(sa)->denied));
}
}
audit_log_format(ab, " peer=");
@@ -142,16 +140,18 @@ static inline int map_signal_num(int sig)
}
/**
- * audit_file_mask - convert mask to permission string
- * @buffer: buffer to write string to (NOT NULL)
+ * audit_signal_mask - convert mask to permission string
* @mask: permission mask to convert
+ *
+ * Returns: pointer to static string
*/
-static void audit_signal_mask(struct audit_buffer *ab, u32 mask)
+static const char *audit_signal_mask(u32 mask)
{
if (mask & MAY_READ)
- audit_log_string(ab, "receive");
+ return "receive";
if (mask & MAY_WRITE)
- audit_log_string(ab, "send");
+ return "send";
+ return "";
}
/**
@@ -164,11 +164,11 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va)
struct common_audit_data *sa = va;
if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
- audit_log_format(ab, " requested_mask=");
- audit_signal_mask(ab, aad(sa)->request);
+ audit_log_format(ab, " requested_mask=%s",
+ audit_signal_mask(aad(sa)->request));
if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
- audit_log_format(ab, " denied_mask=");
- audit_signal_mask(ab, aad(sa)->denied);
+ audit_log_format(ab, " denied_mask=%s",
+ audit_signal_mask(aad(sa)->denied));
}
}
if (aad(sa)->signal == SIGUNKNOWN)
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index d8afc39f663a..fa0e85568450 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -72,16 +72,18 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
{
struct common_audit_data *sa = va;
- audit_log_format(ab, " family=");
if (address_family_names[sa->u.net->family])
- audit_log_string(ab, address_family_names[sa->u.net->family]);
+ audit_log_format(ab, " family=\"%s\"",
+ address_family_names[sa->u.net->family]);
else
- audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
- audit_log_format(ab, " sock_type=");
+ audit_log_format(ab, " family=\"unknown(%d)\"",
+ sa->u.net->family);
if (sock_type_names[aad(sa)->net.type])
- audit_log_string(ab, sock_type_names[aad(sa)->net.type]);
+ audit_log_format(ab, " sock_type=\"%s\"",
+ sock_type_names[aad(sa)->net.type]);
else
- audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type);
+ audit_log_format(ab, " sock_type=\"unknown(%d)\"",
+ aad(sa)->net.type);
audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
if (aad(sa)->request & NET_PERMS_MASK) {
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 2d2bf49016f4..221370794d14 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -427,8 +427,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
a->u.ibendport->port);
break;
case LSM_AUDIT_DATA_LOCKDOWN:
- audit_log_format(ab, " lockdown_reason=");
- audit_log_string(ab, lockdown_reasons[a->u.reason]);
+ audit_log_format(ab, " lockdown_reason=\"%s\"",
+ lockdown_reasons[a->u.reason]);
break;
} /* switch (a->type) */
}
--
1.8.3.1
4 years, 3 months
[PATCH ghak96 v3] audit: issue CWD record to accompany LSM_AUDIT_DATA_* records
by Richard Guy Briggs
The LSM_AUDIT_DATA_* records for PATH, FILE, IOCTL_OP, DENTRY and INODE
are incomplete without the task context of the AUDIT Current Working
Directory record. Add it.
This record addition can't use audit_dummy_context to determine whether
or not to store the record information since the LSM_AUDIT_DATA_*
records are initiated by various LSMs independent of any audit rules.
context->in_syscall is used to determine if it was called in user
context like audit_getname.
Please see the upstream issue
https://github.com/linux-audit/audit-kernel/issues/96
Adapted from Vladis Dronov's v2 patch.
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
Passes audit-testsuite.
Changelog:
v3
- adapt and refactor__audit_getname, don't key on dummy
v2
2020-04-02 vdronov https://www.redhat.com/archives/linux-audit/2020-April/msg00004.html
- convert to standalone CWD record
v1:
2020-03-24 vdronov https://github.com/nefigtut/audit-kernel/commit/df0b55b7ab84e1c9faa588b08...
- add cwd= field to LSM record
include/linux/audit.h | 9 ++++++++-
kernel/auditsc.c | 17 +++++++++++++++--
security/lsm_audit.c | 5 +++++
3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 03c4035a532b..bb850d588e1c 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -292,7 +292,7 @@ extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1,
extern void __audit_syscall_exit(int ret_success, long ret_value);
extern struct filename *__audit_reusename(const __user char *uptr);
extern void __audit_getname(struct filename *name);
-
+extern void __audit_getcwd(void);
extern void __audit_inode(struct filename *name, const struct dentry *dentry,
unsigned int flags);
extern void __audit_file(const struct file *);
@@ -351,6 +351,11 @@ static inline void audit_getname(struct filename *name)
if (unlikely(!audit_dummy_context()))
__audit_getname(name);
}
+static inline void audit_getcwd(void)
+{
+ if (unlikely(audit_context()))
+ __audit_getcwd();
+}
static inline void audit_inode(struct filename *name,
const struct dentry *dentry,
unsigned int aflags) {
@@ -579,6 +584,8 @@ static inline struct filename *audit_reusename(const __user char *name)
}
static inline void audit_getname(struct filename *name)
{ }
+static inline void audit_getcwd(void)
+{ }
static inline void audit_inode(struct filename *name,
const struct dentry *dentry,
unsigned int aflags)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 3a9100e95fda..934ab5b8c1c5 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1891,6 +1891,20 @@ struct filename *
return NULL;
}
+inline void _audit_getcwd(struct audit_context *context)
+{
+ if (!context->pwd.dentry)
+ get_fs_pwd(current->fs, &context->pwd);
+}
+
+void __audit_getcwd(void)
+{
+ struct audit_context *context = audit_context();
+
+ if (context->in_syscall)
+ _audit_getcwd(context);
+}
+
/**
* __audit_getname - add a name to the list
* @name: name to add
@@ -1915,8 +1929,7 @@ void __audit_getname(struct filename *name)
name->aname = n;
name->refcnt++;
- if (!context->pwd.dentry)
- get_fs_pwd(current->fs, &context->pwd);
+ _audit_getcwd(context);
}
static inline int audit_copy_fcaps(struct audit_names *name,
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 2d2bf49016f4..7c555621c2bd 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -241,6 +241,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
audit_log_untrustedstring(ab, inode->i_sb->s_id);
audit_log_format(ab, " ino=%lu", inode->i_ino);
}
+ audit_getcwd();
break;
}
case LSM_AUDIT_DATA_FILE: {
@@ -254,6 +255,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
audit_log_untrustedstring(ab, inode->i_sb->s_id);
audit_log_format(ab, " ino=%lu", inode->i_ino);
}
+ audit_getcwd();
break;
}
case LSM_AUDIT_DATA_IOCTL_OP: {
@@ -269,6 +271,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
}
audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
+ audit_getcwd();
break;
}
case LSM_AUDIT_DATA_DENTRY: {
@@ -283,6 +286,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
audit_log_untrustedstring(ab, inode->i_sb->s_id);
audit_log_format(ab, " ino=%lu", inode->i_ino);
}
+ audit_getcwd();
break;
}
case LSM_AUDIT_DATA_INODE: {
@@ -300,6 +304,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
audit_log_format(ab, " dev=");
audit_log_untrustedstring(ab, inode->i_sb->s_id);
audit_log_format(ab, " ino=%lu", inode->i_ino);
+ audit_getcwd();
break;
}
case LSM_AUDIT_DATA_TASK: {
--
1.8.3.1
4 years, 3 months