From 11ccdd19ec40604d433a809a5c1c61e50c52db29 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Mon, 31 Jul 2023 01:46:13 +0100 Subject: [PATCH] launcher: start unit immediately as unprivileged user It is better to never have privileges rather than start with them and remove them later, as the attack surface is reduced, and there are fewer things to do before being 'ready'. Nowadays systemd can run the service as the appropriate user/group out of the box. When starting as root files in /proc/self/fdinfo/ will be owned as root and set to 400, so we cannot read them. Nowadays it is not necessary to start as root when running under systemd, so just add User/Group with the configured user to the system unit. Add a meson option to let users configure the user, and default to the same as dbus-daemon's default, 'messagebus'. If libaudit support is enabled, add AmbientCapabilities=CAP_AUDIT_WRITE so that we can still write to the audit log. Signed-off-by: Luca Boccassi --- meson.build | 16 ++++++++++++++++ meson_options.txt | 1 + src/units/system/dbus-broker.service.in | 3 +++ src/util/audit.c | 3 +++ src/util/misc.c | 3 +++ 5 files changed, 26 insertions(+) diff --git a/meson.build b/meson.build index b9dd8467..eb600a07 100644 --- a/meson.build +++ b/meson.build @@ -55,6 +55,9 @@ use_audit = get_option('audit') if use_audit dep_libaudit = dependency('audit', version: '>=3.0') dep_libcapng = dependency('libcap-ng', version: '>=0.6') + conf.set('ambientcaps', 'AmbientCapabilities=CAP_AUDIT_WRITE') +else + conf.set('ambientcaps', '') endif # @@ -113,6 +116,19 @@ endforeach add_project_arguments('-DSYSTEM_CONSOLE_USERS=' + acc_sysusers, language: 'c') +# +# Config: user +# + +user = get_option('user') +if user != '' + conf.set('user', 'User=' + user) + conf.set('group', 'Group=' + user) +else + conf.set('user', '') + conf.set('group', '') +endif + # # Global Parameters # diff --git a/meson_options.txt b/meson_options.txt index 15fc72d2..37c8e486 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -6,3 +6,4 @@ option('linux-4-17', type: 'boolean', value: false, description: 'Require linux- option('reference-test', type: 'boolean', value: false, description: 'Run test suite against reference implementation') option('selinux', type: 'boolean', value: false, description: 'SELinux support') option('system-console-users', type: 'array', value: [], description: 'Additional set of names of system-users to be considered at-console') +option('user', type: 'string', value: 'messagebus', description: 'User/group to run the system broker as via its unit file') diff --git a/src/units/system/dbus-broker.service.in b/src/units/system/dbus-broker.service.in index cc5ae361..239ec82e 100644 --- a/src/units/system/dbus-broker.service.in +++ b/src/units/system/dbus-broker.service.in @@ -17,6 +17,9 @@ PrivateTmp=true PrivateDevices=true ExecStart=@bindir@/dbus-broker-launch --scope system --audit ExecReload=@bindir@/busctl call org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus ReloadConfig +@user@ +@group@ +@ambientcaps@ [Install] Alias=dbus.service diff --git a/src/util/audit.c b/src/util/audit.c index 15a9d520..ffc749b5 100644 --- a/src/util/audit.c +++ b/src/util/audit.c @@ -42,6 +42,9 @@ int util_audit_drop_permissions(uint32_t uid, uint32_t gid) { */ if (geteuid() != 0) { + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_AUDIT_WRITE)) + return 0; /* Nothing to do */ + /* * For compatibility to dbus-daemon, this must be * non-fatal. diff --git a/src/util/misc.c b/src/util/misc.c index c0206db9..89442704 100644 --- a/src/util/misc.c +++ b/src/util/misc.c @@ -33,6 +33,9 @@ uint64_t util_umul64_saturating(uint64_t a, uint64_t b) { int util_drop_permissions(uint32_t uid, uint32_t gid) { int r; + if (geteuid () == uid && getuid () == uid && getegid () == gid && getgid () == gid) + return 0; /* Nothing to do */ + /* for compatibility to dbus-daemon, this must be non-fatal */ setgroups(0, NULL);