From 7e888025dc76f4cac954480eeec53ff4b0008566 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Thu, 14 Dec 2023 12:29:47 +0100 Subject: [PATCH] umockdev-record: Record SELinux context --- meson.build | 20 +++++++++++++++----- src/selinux.vapi | 6 ++++++ src/umockdev-record.vala | 14 +++++++++++++- tests/test-umockdev-record.vala | 10 ++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 src/selinux.vapi diff --git a/meson.build b/meson.build index d82eefa..37feb1b 100644 --- a/meson.build +++ b/meson.build @@ -66,7 +66,15 @@ meson.add_dist_script(srcdir / 'getversion.sh') # dependencies # +optional_defines = [] + dl = cc.find_library('dl') +selinux = cc.find_library('libselinux', required: false) +if selinux.found() + if cc.check_header('selinux/selinux.h') + optional_defines += ['--define=HAVE_SELINUX'] + endif +endif glib = dependency('glib-2.0', version: '>= 2.32.0') gobject = dependency('gobject-2.0', version: '>= 2.32.0') @@ -87,6 +95,7 @@ vala_libutil = cc.find_library('util') # local VAPIs vapi_config = valac.find_library('config', dirs: srcdir) vapi_ioctl = valac.find_library('ioctl', dirs: srcdir) +vapi_selinux = valac.find_library('selinux', dirs: srcdir) vapi_assertions = valac.find_library('assertions', dirs: testsdir) # @@ -141,7 +150,7 @@ umockdev_lib = shared_library('umockdev', 'src/debug.c'], vala_vapi: 'umockdev-1.0.vapi', vala_gir: 'UMockdev-1.0.gir', - dependencies: [glib, gobject, gio, gio_unix, vapi_posix, vapi_linux, vapi_linux_fixes, vala_libudev, vala_libutil, vapi_ioctl, libpcap], + dependencies: [glib, gobject, gio, gio_unix, vapi_posix, vapi_linux, vapi_linux_fixes, vala_libudev, vala_libutil, vapi_ioctl, vapi_selinux, libpcap], link_with: [umockdev_utils_lib], link_depends: ['src/umockdev.map'], link_args: [ @@ -151,7 +160,7 @@ umockdev_lib = shared_library('umockdev', ], vala_args: ['--define=INTERNAL_REGISTER_API', '--define=INTERNAL_UNREGISTER_PATH_API', - '--vapidir=@0@/src'.format(meson.current_source_dir())], + '--vapidir=@0@/src'.format(meson.current_source_dir())] + optional_defines, include_directories: include_directories('src'), version: lib_version, install: true, @@ -201,11 +210,11 @@ umockdev_record_exe = executable('umockdev-record', 'src/ioctl_tree.c', 'src/utils.c', 'src/debug.c'], - dependencies: [glib, gobject, gio_unix, vapi_posix, vapi_config, vapi_ioctl, libpcap], + dependencies: [glib, gobject, gio_unix, vapi_posix, vapi_config, vapi_ioctl, vapi_selinux, libpcap, selinux], link_with: [umockdev_utils_lib], vala_args: ['--define=INTERNAL_REGISTER_API', '--define=INTERNAL_UNREGISTER_ALL_API', - '--vapidir=@0@/src'.format(meson.current_source_dir())], + '--vapidir=@0@/src'.format(meson.current_source_dir())] + optional_defines, include_directories: include_directories('src'), install: true) @@ -280,7 +289,8 @@ test('umockdev-run', executable('test-umockdev-run', test('umockdev-record', executable('test-umockdev-record', 'tests/test-umockdev-record.vala', dependencies: [glib, gobject, gio, gio_unix, vapi_posix, vapi_linux, vapi_assertions, vapi_config, vala_libutil], - link_with: [umockdev_lib, umockdev_utils_lib]), + link_with: [umockdev_lib, umockdev_utils_lib], + vala_args: optional_defines), depends: [umockdev_record_exe, preload_lib, test_readbyte_exe, test_chatter_exe, test_chatter_stream_exe], suite: 'fails-valgrind') diff --git a/src/selinux.vapi b/src/selinux.vapi new file mode 100644 index 0000000..39c75cb --- /dev/null +++ b/src/selinux.vapi @@ -0,0 +1,6 @@ +[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "selinux/selinux.h")] +namespace Selinux { + int lgetfilecon (string path, out string context); + int lsetfilecon (string path, string context); + void freecon (string context); +} diff --git a/src/umockdev-record.vala b/src/umockdev-record.vala index bf0e644..8d8fe22 100644 --- a/src/umockdev-record.vala +++ b/src/umockdev-record.vala @@ -21,6 +21,9 @@ */ using UMockdevUtils; +#if HAVE_SELINUX +using Selinux; +#endif static void devices_from_dir (string dir, ref GenericArray devs) @@ -251,7 +254,16 @@ record_device(string dev) continue; if (line.has_prefix("N: ")) { - line = line + dev_contents("/dev/" + line.substring(3).chomp()); + string devpath = "/dev/" + line.substring(3).chomp(); + line = line + dev_contents(devpath); + + // record SELinux context +#if HAVE_SELINUX + string context; + int res = Selinux.lgetfilecon(devpath, out context); + if (res > 0) + properties.append("E: __DEVCONTEXT=" + context); +#endif } stdout.puts(line); stdout.putc('\n'); diff --git a/tests/test-umockdev-record.vala b/tests/test-umockdev-record.vala index abef9ec..37e746f 100644 --- a/tests/test-umockdev-record.vala +++ b/tests/test-umockdev-record.vala @@ -196,6 +196,16 @@ t_system_single () assert_in("E: DEVNAME=/dev/null", sout); assert_in("P: /devices/virtual/mem/null", sout); assert_in("E: DEVNAME=/dev/zero", sout); +#if HAVE_SELINUX + // we may run on a system without SELinux + // check if /sys/fs/selinux exists + if (FileUtils.test("/sys/fs/selinux", FileTest.EXISTS)) { + assert_in("E: __DEVCONTEXT=system_u:object_r:null_device_t:s0\n", sout); + assert_in("E: __DEVCONTEXT=system_u:object_r:zero_device_t:s0\n", sout); + } else { + assert(!sout.contains("E: __DEVCONTEXT")); + } +#endif } // system /sys: umockdev-record --all works and result loads back