summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2020-04-09 12:39:57 +0200
committerFrediano Ziglio <fziglio@redhat.com>2020-04-16 10:07:49 +0100
commitc27f2874a2f6f93be6fcba5f8234957eec93229c (patch)
treeef7ac5cac52cc529747648cb4b547424f59f0dd4
parent09111bd1a4e8969863e592717db936d940093521 (diff)
usb-acl-helper: also drop capabilities with libcap-ng
On file systems without capabilities attributes, drop capabilities at runtime from the start. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
-rw-r--r--meson.build6
-rw-r--r--meson_options.txt4
-rw-r--r--src/spice-client-glib-usb-acl-helper.c32
3 files changed, 38 insertions, 4 deletions
diff --git a/meson.build b/meson.build
index 01755be..91c6ec2 100644
--- a/meson.build
+++ b/meson.build
@@ -191,6 +191,12 @@ if d1.found() and d2.found() and d3.found()
spice_gtk_has_usbredir = true
endif
+d = dependency('libcap-ng', required : get_option('libcap-ng'))
+if d.found()
+ spice_gtk_config_data.set('USE_LIBCAP_NG', '1')
+ spice_acl_deps += d
+endif
+
# polkit
spice_gtk_has_polkit = false
d = dependency('polkit-gobject-1', version : '>= 0.101', required : get_option('polkit'))
diff --git a/meson_options.txt b/meson_options.txt
index 7d2ea30..88ca9b4 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -15,6 +15,10 @@ option('usbredir',
type : 'feature',
description : 'Enable usbredir support')
+option('libcap-ng',
+ type : 'feature',
+ description: 'Enable libcap-ng support for the USB acl helper')
+
option('polkit',
type : 'feature',
description : 'Enable PolicyKit support for the USB acl helper')
diff --git a/src/spice-client-glib-usb-acl-helper.c b/src/spice-client-glib-usb-acl-helper.c
index 4bfe96e..17113e6 100644
--- a/src/spice-client-glib-usb-acl-helper.c
+++ b/src/spice-client-glib-usb-acl-helper.c
@@ -32,6 +32,9 @@
#include <gio/gunixinputstream.h>
#include <polkit/polkit.h>
#include <sys/acl.h>
+#ifdef USE_LIBCAP_NG
+#include <cap-ng.h>
+#endif
#define FATAL_ERROR(...) \
do { \
@@ -288,15 +291,36 @@ int main(void)
pid_t parent_pid;
GInputStream *stdin_unix_stream;
- /* Nuke the environment to get a well-known and sanitized
- * environment to avoid attacks via e.g. the DBUS_SYSTEM_BUS_ADDRESS
- * environment variable and similar.
- */
+ /* Nuke the environment to get a well-known and sanitized
+ * environment to avoid attacks via e.g. the DBUS_SYSTEM_BUS_ADDRESS
+ * environment variable and similar.
+ */
if (clearenv () != 0) {
FATAL_ERROR("Error clearing environment: %s\n", g_strerror (errno));
return 1;
}
+#ifdef USE_LIBCAP_NG
+ /* When SUID root, keep only CAP_FOWNER and change credentials */
+ if (geteuid() == 0 && getuid() != geteuid()) {
+ int rv;
+
+ capng_clear(CAPNG_SELECT_BOTH);
+ rv = capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_FOWNER);
+ if (rv < 0) {
+ FATAL_ERROR("Failed to update the capabilities: %d\n", rv);
+ return 1;
+ }
+
+ rv = capng_change_id(getuid(), getgid(), CAPNG_CLEAR_BOUNDING);
+ if (rv < 0) {
+ FATAL_ERROR("Failed to drop capabilities: %d\n", rv);
+ return 1;
+ }
+ }
+#endif
+
+
loop = g_main_loop_new(NULL, FALSE);
authority = polkit_authority_get_sync(NULL, NULL);