From 6dd2c3bcd1c4147fb6bbcc16327c48b709d2528e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 15 Mar 2023 20:39:28 +0000 Subject: [PATCH 1/3] Add separate label for cgroup's memory.pressure files Required to enable notifications on memory pressure events, need to write to the file to start receiving them. This will be used by all systemd daemons, and eventually external daemons that subscribe to the same interface too. See: https://github.com/systemd/systemd/blob/main/docs/MEMORY_PRESSURE.md Signed-off-by: Luca Boccassi --- policy/modules/kernel/filesystem.if | 129 +++++++++++++++++++--------- policy/modules/kernel/filesystem.te | 8 ++ policy/modules/system/init.te | 9 ++ 3 files changed, 105 insertions(+), 41 deletions(-) diff --git a/policy/modules/kernel/filesystem.if b/policy/modules/kernel/filesystem.if index bf4484297..b3b5dfcc4 100644 --- a/policy/modules/kernel/filesystem.if +++ b/policy/modules/kernel/filesystem.if @@ -725,10 +725,10 @@ interface(`fs_manage_bpf_files',` # interface(`fs_mount_cgroup', ` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - allow $1 cgroup_t:filesystem mount; + allow $1 cgroup_types:filesystem mount; ') ######################################## @@ -743,10 +743,10 @@ interface(`fs_mount_cgroup', ` # interface(`fs_remount_cgroup', ` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - allow $1 cgroup_t:filesystem remount; + allow $1 cgroup_types:filesystem remount; ') ######################################## @@ -761,10 +761,10 @@ interface(`fs_remount_cgroup', ` # interface(`fs_unmount_cgroup', ` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - allow $1 cgroup_t:filesystem unmount; + allow $1 cgroup_types:filesystem unmount; ') ######################################## @@ -779,10 +779,10 @@ interface(`fs_unmount_cgroup', ` # interface(`fs_getattr_cgroup',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - allow $1 cgroup_t:filesystem getattr; + allow $1 cgroup_types:filesystem getattr; ') ######################################## @@ -797,10 +797,10 @@ interface(`fs_getattr_cgroup',` # interface(`fs_search_cgroup_dirs',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - search_dirs_pattern($1, cgroup_t, cgroup_t) + search_dirs_pattern($1, cgroup_types, cgroup_types) dev_search_sysfs($1) ') @@ -816,10 +816,10 @@ interface(`fs_search_cgroup_dirs',` # interface(`fs_list_cgroup_dirs', ` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - list_dirs_pattern($1, cgroup_t, cgroup_t) + list_dirs_pattern($1, cgroup_types, cgroup_types) dev_search_sysfs($1) ') @@ -873,10 +873,10 @@ interface(`fs_create_cgroup_dirs',` # interface(`fs_delete_cgroup_dirs', ` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - delete_dirs_pattern($1, cgroup_t, cgroup_t) + delete_dirs_pattern($1, cgroup_types, cgroup_types) dev_search_sysfs($1) ') @@ -892,11 +892,11 @@ interface(`fs_delete_cgroup_dirs', ` # interface(`fs_manage_cgroup_dirs',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - manage_dirs_pattern($1, cgroup_t, cgroup_t) + manage_dirs_pattern($1, cgroup_types, cgroup_types) dev_search_sysfs($1) ') @@ -912,10 +912,10 @@ interface(`fs_manage_cgroup_dirs',` # interface(`fs_relabel_cgroup_dirs',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - relabel_dirs_pattern($1, cgroup_t, cgroup_t) + relabel_dirs_pattern($1, cgroup_types, cgroup_types) ') ######################################## @@ -930,10 +930,10 @@ interface(`fs_relabel_cgroup_dirs',` # interface(`fs_getattr_cgroup_files',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - getattr_files_pattern($1, cgroup_t, cgroup_t) + getattr_files_pattern($1, cgroup_types, cgroup_types) fs_search_tmpfs($1) dev_search_sysfs($1) ') @@ -950,12 +950,12 @@ interface(`fs_getattr_cgroup_files',` # interface(`fs_read_cgroup_files',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - read_files_pattern($1, cgroup_t, cgroup_t) - read_lnk_files_pattern($1, cgroup_t, cgroup_t) + read_files_pattern($1, cgroup_types, cgroup_types) + read_lnk_files_pattern($1, cgroup_types, cgroup_types) dev_search_sysfs($1) ') @@ -991,11 +991,11 @@ interface(`fs_create_cgroup_files',` # interface(`fs_watch_cgroup_files',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - allow $1 cgroup_t:file watch; + allow $1 cgroup_types:file watch; ') ######################################## @@ -1010,11 +1010,11 @@ interface(`fs_watch_cgroup_files',` # interface(`fs_create_cgroup_links',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - create_lnk_files_pattern($1, cgroup_t, cgroup_t) - rw_lnk_files_pattern($1, cgroup_t, cgroup_t) + create_lnk_files_pattern($1, cgroup_types, cgroup_types) + rw_lnk_files_pattern($1, cgroup_types, cgroup_types) dev_search_sysfs($1) ') @@ -1030,10 +1030,10 @@ interface(`fs_create_cgroup_links',` # interface(`fs_write_cgroup_files', ` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - write_files_pattern($1, cgroup_t, cgroup_t) + write_files_pattern($1, cgroup_types, cgroup_types) dev_search_sysfs($1) ') @@ -1049,11 +1049,11 @@ interface(`fs_write_cgroup_files', ` # interface(`fs_rw_cgroup_files',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - rw_files_pattern($1, cgroup_t, cgroup_t) - read_lnk_files_pattern($1, cgroup_t, cgroup_t) + rw_files_pattern($1, cgroup_types, cgroup_types) + read_lnk_files_pattern($1, cgroup_types, cgroup_types) dev_search_sysfs($1) ') @@ -1071,10 +1071,10 @@ interface(`fs_rw_cgroup_files',` # interface(`fs_dontaudit_rw_cgroup_files',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - dontaudit $1 cgroup_t:file rw_file_perms; + dontaudit $1 cgroup_types:file rw_file_perms; ') ######################################## @@ -1089,11 +1089,11 @@ interface(`fs_dontaudit_rw_cgroup_files',` # interface(`fs_manage_cgroup_files',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - manage_files_pattern($1, cgroup_t, cgroup_t) + manage_files_pattern($1, cgroup_types, cgroup_types) dev_search_sysfs($1) ') @@ -1109,10 +1109,10 @@ interface(`fs_manage_cgroup_files',` # interface(`fs_relabel_cgroup_symlinks',` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - relabel_lnk_files_pattern($1, cgroup_t, cgroup_t) + relabel_lnk_files_pattern($1, cgroup_types, cgroup_types) ') ######################################## @@ -1145,10 +1145,10 @@ interface(`fs_watch_cgroup_dirs', ` # interface(`fs_mounton_cgroup', ` gen_require(` - type cgroup_t; + attribute cgroup_types; ') - allow $1 cgroup_t:dir mounton; + allow $1 cgroup_types:dir mounton; ') ######################################## @@ -1187,6 +1187,53 @@ interface(`fs_cgroup_filetrans',` dev_search_sysfs($1) ') +######################################## +## +## Create an object in a cgroup tmpfs filesystem, with the memory_pressure_t +## type using a type transition. +## +## +## +## Domain allowed access. +## +## +## +## +## The object class of the object being created. +## +## +## +## +## The name of the object being created. +## +## +# +interface(`fs_cgroup_filetrans_memory_pressure',` + gen_require(` + type memory_pressure_t; + ') + + fs_cgroup_filetrans($1, memory_pressure_t, $2, $3) +') + +######################################## +## +## Allow managing a cgroup's memory.pressure file to get notifications +## +## +## +## Source domain +## +## +# +interface(`fs_watch_memory_pressure',` + gen_require(` + type memory_pressure_t; + ') + + allow $1 memory_pressure_t:file { rw_file_perms setattr }; +') + ######################################## ## ## Do not audit attempts to read diff --git a/policy/modules/kernel/filesystem.te b/policy/modules/kernel/filesystem.te index c56678135..67aa29ed9 100644 --- a/policy/modules/kernel/filesystem.te +++ b/policy/modules/kernel/filesystem.te @@ -86,12 +86,20 @@ fs_type(capifs_t) files_mountpoint(capifs_t) genfscon capifs / gen_context(system_u:object_r:capifs_t,s0) +attribute cgroup_types; type cgroup_t; +typeattribute cgroup_t cgroup_types; fs_type(cgroup_t) files_mountpoint(cgroup_t) dev_associate_sysfs(cgroup_t) genfscon cgroup / gen_context(system_u:object_r:cgroup_t,s0) genfscon cgroup2 / gen_context(system_u:object_r:cgroup_t,s0) +# When running under systemd, the cgroup file memory.pressure will have this +# separate label, to allow unprivileged process to access it without accessing +# the rest of the cgroup tree. +type memory_pressure_t; +typeattribute memory_pressure_t cgroup_types; +dev_associate_sysfs(memory_pressure_t) type configfs_t; fs_type(configfs_t) diff --git a/policy/modules/system/init.te b/policy/modules/system/init.te index 1b6bbefb9..38d0c2538 100644 --- a/policy/modules/system/init.te +++ b/policy/modules/system/init.te @@ -1171,6 +1171,15 @@ ifdef(`init_systemd',` systemd_start_power_units(initrc_t) systemd_watch_networkd_runtime_dirs(initrc_t) + # Ensures the memory.pressure cgroup file is labelled differently, so + # that processes can manage it without having access to the rest of the + # cgroup tree. This is a special file so each open is an independent, + # separate instance that cannot affect already opened ones, so it is not + # necessary to lock it down on a process-by-process base. This is useful + # to allow receiving notifications when memory pressure is high, see: + # https://systemd.io/MEMORY_PRESSURE/ + fs_cgroup_filetrans_memory_pressure(init_t, file, "memory.pressure") + optional_policy(` # create /var/lock/lvm/ lvm_create_lock_dirs(initrc_t) From 6ecba6ff80e121df23a72b776921581767f84119 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 15 Mar 2023 22:26:11 +0000 Subject: [PATCH 2/3] systemd: also allow to mounton memory.pressure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mar 15 22:15:35 localhost audit[1607]: AVC avc:  denied  { mounton } for  pid=1607 comm="(esetinfo)" path="/run/systemd/unit-root/sys/fs/cgroup/system.slice/socresetinfo.service/memory.pressure" dev="cgroup2" ino=2522 scontext=system_u:system_r:init_t tcontext=system_u:object_r:memory_pressure_t tclass=file permissive=1 Signed-off-by: Luca Boccassi --- policy/modules/kernel/filesystem.if | 18 ++++++++++++++++++ policy/modules/system/init.te | 1 + 2 files changed, 19 insertions(+) diff --git a/policy/modules/kernel/filesystem.if b/policy/modules/kernel/filesystem.if index b3b5dfcc4..cbaab2c86 100644 --- a/policy/modules/kernel/filesystem.if +++ b/policy/modules/kernel/filesystem.if @@ -1151,6 +1151,24 @@ interface(`fs_mounton_cgroup', ` allow $1 cgroup_types:dir mounton; ') +######################################## +## +## Mount on cgroup files. +## +## +## +## Domain allowed access. +## +## +# +interface(`fs_mounton_cgroup_files', ` + gen_require(` + attribute cgroup_types; + ') + + allow $1 cgroup_types:file mounton; +') + ######################################## ## ## Create an object in a cgroup tmpfs filesystem, with a private diff --git a/policy/modules/system/init.te b/policy/modules/system/init.te index 38d0c2538..799d23081 100644 --- a/policy/modules/system/init.te +++ b/policy/modules/system/init.te @@ -1179,6 +1179,7 @@ ifdef(`init_systemd',` # to allow receiving notifications when memory pressure is high, see: # https://systemd.io/MEMORY_PRESSURE/ fs_cgroup_filetrans_memory_pressure(init_t, file, "memory.pressure") + fs_mounton_cgroup_files(init_t) optional_policy(` # create /var/lock/lvm/ From d0d4e8fd73c5835fd1a63e12cb1ab55b4ae35b23 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 15 Mar 2023 20:40:26 +0000 Subject: [PATCH 3/3] systemd: allow daemons to access memory.pressure These services are hooked up to the memory.pressure interface, so allow them to access the file. Jan 26 08:12:21 localhost audit[202]: AVC avc: denied { getattr } for pid=202 comm="systemd-journal" path="/sys/fs/cgroup/system.slice/systemd-journald.service/memory.pressure" dev="cgroup2" ino=557 scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[379]: AVC avc: denied { getattr } for pid=379 comm="systemd-resolve" path="/sys/fs/cgroup/system.slice/systemd-resolved.service/memory.pressure" dev="cgroup2" ino=1463 scontext=system_u:system_r:systemd_resolved_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Mar 10 19:49:01 localhost audit[475]: AVC avc: denied { getattr } for pid=475 comm="systemd-network" path="/sys/fs/cgroup/system.slice/systemd-networkd.service/memory.pressure" dev="cgroup2" ino=1595 scontext=system_u:system_r:systemd_networkd_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Mar 10 19:49:02 localhost audit[491]: AVC avc: denied { getattr } for pid=491 comm="systemd-portabl" path="/sys/fs/cgroup/system.slice/systemd-portabled.service/memory.pressure" dev="cgroup2" ino=1859 scontext=system_u:system_r:systemd_portabled_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Mar 10 19:49:02 localhost audit[490]: AVC avc: denied { write } for pid=490 comm="systemd-logind" name="memory.pressure" dev="cgroup2" ino=1826 scontext=system_u:system_r:systemd_logind_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[202]: AVC avc: denied { getattr } for pid=202 comm="systemd-journal" path="/sys/fs/cgroup/system.slice/systemd-journald.service/memory.pressure" dev="cgroup2" ino=557 scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[382]: AVC avc: denied { getattr } for pid=382 comm="systemd-resolve" path="/sys/fs/cgroup/system.slice/systemd-resolved.service/memory.pressure" dev="cgroup2" ino=1463 scontext=system_u:system_r:systemd_resolved_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Mar 10 19:57:56 localhost audit[479]: AVC avc: denied { getattr } for pid=479 comm="systemd-network" path="/sys/fs/cgroup/system.slice/systemd-networkd.service/memory.pressure" dev="cgroup2" ino=1595 scontext=system_u:system_r:systemd_networkd_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Mar 10 19:57:56 localhost audit[493]: AVC avc: denied { getattr } for pid=493 comm="systemd-portabl" path="/sys/fs/cgroup/system.slice/systemd-portabled.service/memory.pressure" dev="cgroup2" ino=1859 scontext=system_u:system_r:systemd_portabled_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Mar 10 19:57:56 localhost audit[492]: AVC avc: denied { write } for pid=492 comm="systemd-logind" name="memory.pressure" dev="cgroup2" ino=1826 scontext=system_u:system_r:systemd_logind_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[204]: AVC avc: denied { getattr } for pid=204 comm="systemd-journal" path="/sys/fs/cgroup/system.slice/systemd-journald.service/memory.pressure" dev="cgroup2" ino=526 scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[316]: AVC avc: denied { getattr } for pid=316 comm="systemd-resolve" path="/sys/fs/cgroup/system.slice/systemd-resolved.service/memory.pressure" dev="cgroup2" ino=1234 scontext=system_u:system_r:systemd_resolved_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[359]: AVC avc: denied { getattr } for pid=359 comm="systemd-network" path="/sys/fs/cgroup/system.slice/systemd-networkd.service/memory.pressure" dev="cgroup2" ino=1564 scontext=system_u:system_r:systemd_networkd_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[350]: AVC avc: denied { write } for pid=350 comm="systemd-logind" name="memory.pressure" dev="cgroup2" ino=1531 scontext=system_u:system_r:systemd_logind_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[203]: AVC avc: denied { getattr } for pid=203 comm="systemd-journal" path="/sys/fs/cgroup/system.slice/systemd-journald.service/memory.pressure" dev="cgroup2" ino=526 scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[312]: AVC avc: denied { getattr } for pid=312 comm="systemd-resolve" path="/sys/fs/cgroup/system.slice/systemd-resolved.service/memory.pressure" dev="cgroup2" ino=1234 scontext=system_u:system_r:systemd_resolved_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[351]: AVC avc: denied { getattr } for pid=351 comm="systemd-network" path="/sys/fs/cgroup/system.slice/systemd-networkd.service/memory.pressure" dev="cgroup2" ino=1564 scontext=system_u:system_r:systemd_networkd_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[342]: AVC avc: denied { write } for pid=342 comm="systemd-logind" name="memory.pressure" dev="cgroup2" ino=1531 scontext=system_u:system_r:systemd_logind_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Jan 26 08:12:21 localhost audit[201]: AVC avc: denied { open } for pid=201 comm="systemd-journal" path="/sys/fs/cgroup/system.slice/systemd-journald.service/memory.pressure" dev="cgroup2" ino=557 scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Mar 13 17:00:57 localhost audit[490]: AVC avc: denied { open } for pid=490 comm="systemd-portabl" path="/sys/fs/cgroup/system.slice/systemd-portabled.service/memory.pressure" dev="cgroup2" ino=1859 scontext=system_u:system_r:systemd_portabled_t tcontext=system_u:object_r:cgroup_t tclass=file permissive=0 Signed-off-by: Luca Boccassi --- policy/modules/services/ntp.te | 1 + policy/modules/system/logging.te | 1 + policy/modules/system/systemd.te | 5 +++++ policy/modules/system/udev.te | 1 + 4 files changed, 8 insertions(+) diff --git a/policy/modules/services/ntp.te b/policy/modules/services/ntp.te index 16494ba61..8a8534294 100644 --- a/policy/modules/services/ntp.te +++ b/policy/modules/services/ntp.te @@ -156,6 +156,7 @@ ifdef(`init_systemd',` allow ntpd_t self:capability { fowner setpcap }; init_read_state(ntpd_t) init_reload(ntpd_t) + fs_watch_memory_pressure(ntpd_t) # for /var/lib/systemd/clock init_list_var_lib_dirs(ntpd_t) diff --git a/policy/modules/system/logging.te b/policy/modules/system/logging.te index 1dd4813d1..f10a1f6ba 100644 --- a/policy/modules/system/logging.te +++ b/policy/modules/system/logging.te @@ -549,6 +549,7 @@ ifdef(`init_systemd',` domain_read_all_domains_state(syslogd_t) fs_list_cgroup_dirs(syslogd_t) + fs_watch_memory_pressure(syslogd_t) init_create_runtime_dirs(syslogd_t) init_daemon_runtime_file(syslogd_runtime_t, dir, "syslogd") diff --git a/policy/modules/system/systemd.te b/policy/modules/system/systemd.te index ee8119cf3..de5be835b 100644 --- a/policy/modules/system/systemd.te +++ b/policy/modules/system/systemd.te @@ -873,6 +873,7 @@ fs_read_efivarfs_files(systemd_logind_t) fs_relabelfrom_tmpfs_dirs(systemd_logind_t) fs_unmount_tmpfs(systemd_logind_t) fs_getattr_xattr_fs(systemd_logind_t) +fs_watch_memory_pressure(systemd_logind_t) selinux_use_status_page(systemd_logind_t) @@ -1020,6 +1021,7 @@ fs_getattr_cgroup(systemd_machined_t) fs_getattr_tmpfs(systemd_machined_t) fs_getattr_xattr_fs(systemd_machined_t) fs_read_nsfs_files(systemd_machined_t) +fs_watch_memory_pressure(systemd_machined_t) selinux_getattr_fs(systemd_machined_t) @@ -1126,6 +1128,7 @@ files_list_runtime(systemd_networkd_t) fs_getattr_all_fs(systemd_networkd_t) fs_search_cgroup_dirs(systemd_networkd_t) fs_read_nsfs_files(systemd_networkd_t) +fs_watch_memory_pressure(systemd_networkd_t) auth_use_nsswitch(systemd_networkd_t) @@ -1248,6 +1251,7 @@ fs_mount_tmpfs(systemd_nspawn_t) fs_remount_tmpfs(systemd_nspawn_t) fs_remount_xattr_fs(systemd_nspawn_t) fs_read_cgroup_files(systemd_nspawn_t) +fs_watch_memory_pressure(systemd_nspawn_t) term_getattr_generic_ptys(systemd_nspawn_t) term_getattr_pty_fs(systemd_nspawn_t) @@ -1505,6 +1509,7 @@ fs_getattr_all_fs(systemd_resolved_t) fs_search_cgroup_dirs(systemd_resolved_t) fs_search_tmpfs(systemd_resolved_t) fs_search_ramfs(systemd_resolved_t) +fs_watch_memory_pressure(systemd_resolved_t) init_dgram_send(systemd_resolved_t) diff --git a/policy/modules/system/udev.te b/policy/modules/system/udev.te index 90a71239e..af9463a38 100644 --- a/policy/modules/system/udev.te +++ b/policy/modules/system/udev.te @@ -143,6 +143,7 @@ fs_read_cgroup_files(udev_t) fs_rw_anon_inodefs_files(udev_t) fs_search_tracefs(udev_t) fs_manage_efivarfs_files(udev_t) +fs_watch_memory_pressure(udev_t) mls_file_read_all_levels(udev_t) mls_file_write_all_levels(udev_t)