summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCosimo Alfarano <cosimo.alfarano@collabora.co.uk>2011-01-24 15:00:00 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2011-02-25 13:16:04 +0000
commite0bc10ec873f9830d01c70b34095413033d97456 (patch)
treeab8923adec40dc26584e09f48a34670a39326e52
parentde99ea078f0b2e31d1db374716bb44899ceb4c55 (diff)
Make activated processes not inherit oom_adjmaemo-misc
This patch resets the OOM protection level to 0 before exec()uting a new service. For the session bus it is done in the do_exec() (as child_setup). For the system bus it is done in the activation helper, being setuid root, before exec()uting the actual service. The system bus process' /proc/self/oom_adj is owned by root without write permission to the world, but the process is running as non-root user. This makes impossible for dbus-spawn.c's do_exec() properly reset the OOM protection when running as system bus. Based on Kimmo Hämäläinen <kimmo.hamalainen@nokia.com> patch, dated 13 Aug 2007. Bug: https://bugs.freedesktop.org//show_bug.cgi?id=32851 Bug-NB: NB#65462
-rw-r--r--bus/activation-helper.c3
-rw-r--r--bus/activation.c21
-rw-r--r--dbus/dbus-sysdeps-util-unix.c33
-rw-r--r--dbus/dbus-sysdeps-util-win.c13
-rw-r--r--dbus/dbus-sysdeps.h10
5 files changed, 79 insertions, 1 deletions
diff --git a/bus/activation-helper.c b/bus/activation-helper.c
index baba8f04..cf18daae 100644
--- a/bus/activation-helper.c
+++ b/bus/activation-helper.c
@@ -3,6 +3,7 @@
* user. This file is security sensitive.
*
* Copyright (C) 2007 Red Hat, Inc.
+ * Copyright (C) 2011 Nokia Corp.
*
* Licensed under the Academic Free License version 2.1
*
@@ -359,6 +360,8 @@ exec_for_correct_user (char *exec, char *user, DBusError *error)
retval = TRUE;
argv = NULL;
+ _dbus_reset_process_attributes ();
+
if (!switch_user (user, error))
return FALSE;
diff --git a/bus/activation.c b/bus/activation.c
index 7b2a72bc..be78bc72 100644
--- a/bus/activation.c
+++ b/bus/activation.c
@@ -4,6 +4,7 @@
* Copyright (C) 2003 CodeFactory AB
* Copyright (C) 2003 Red Hat, Inc.
* Copyright (C) 2004 Imendio HB
+ * Copyright (C) 2011 Nokia Corp.
*
* Licensed under the Academic Free License version 2.1
*
@@ -1665,6 +1666,24 @@ out:
return retval;
}
+static void
+spawned_child_setup (void *user_data)
+{
+ BusActivation *activation;
+
+ activation = user_data;
+
+ if (activation == NULL)
+ return;
+
+ /* Skip resetting process' attributes for the system bus: the spawned
+ * process to setup will be the activation helper, which in turn will exec()
+ * the service. Let the activation helper reset them just before the exec(),
+ * later, speeding up the spawning process */
+ if (bus_context_get_servicehelper (activation->context) == NULL)
+ _dbus_reset_process_attributes ();
+}
+
dbus_bool_t
bus_activation_activate_service (BusActivation *activation,
DBusConnection *connection,
@@ -2085,7 +2104,7 @@ bus_activation_activate_service (BusActivation *activation,
_dbus_verbose ("Spawning %s ...\n", argv[0]);
if (!_dbus_spawn_async_with_babysitter (&pending_activation->babysitter, argv,
envp,
- NULL, activation,
+ spawned_child_setup, activation,
error))
{
_dbus_verbose ("Failed to spawn child\n");
diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c
index a9ccee13..8da73e39 100644
--- a/dbus/dbus-sysdeps-util-unix.c
+++ b/dbus/dbus-sysdeps-util-unix.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
* Copyright (C) 2003 CodeFactory AB
+ * Copyright (C) 2011 Nokia Corp.
*
* Licensed under the Academic Free License version 2.1
*
@@ -1166,3 +1167,35 @@ fail:
_dbus_string_free (&path);
return FALSE;
}
+
+/**
+ * Reset the some of the current process' attributes.
+ * To be used before exec()uting a service.
+ *
+ * Note: for the system bus, it should be used in the activation helper, and
+ * not in the child_setup for _dbus_spawn_async_with_babysitter(), which would
+ * spawn the helper and not directly the service.
+ *
+ * For example it sets OOM protection to 0.
+ */
+void
+_dbus_reset_process_attributes (void)
+{
+ /* OOM Protection is Linux kernel specific */
+#ifdef __linux__
+ int oom_adj_fd;
+
+ /* Note: when running as system bus, the user running the process won't be
+ * able to open the file for writing, as it's owned by root without writing
+ * permission to the world. It won't cause any harm to execute it, though it
+ * will cause a context switch, slowing down the service spawning */
+ oom_adj_fd = open ("/proc/self/oom_adj", O_WRONLY|O_SYNC);
+ if (oom_adj_fd >= 0)
+ {
+ /* reset OOM protection to prevent spawned services inheriting it */
+ write (oom_adj_fd, "0", sizeof (char));
+ close (oom_adj_fd);
+ }
+#endif /* __linux__ */
+}
+
diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c
index 9b3421e8..1c6d9dde 100644
--- a/dbus/dbus-sysdeps-util-win.c
+++ b/dbus/dbus-sysdeps-util-win.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
* Copyright (C) 2003 CodeFactory AB
+ * Copyright (C) 2011 Nokia Corp.
*
* Licensed under the Academic Free License version 2.1
*
@@ -1530,3 +1531,15 @@ _dbus_command_for_pid (unsigned long pid,
// FIXME
return FALSE;
}
+
+/**
+ * Reset the some of the current process' attributes.
+ *
+ * It is currently a do-nothing function as Windows does not need to reset any
+ * attributes before executing services */
+void
+_dbus_reset_process_attributes (void)
+{
+ /* do nothing */
+}
+
diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h
index 22d7969e..a411aa05 100644
--- a/dbus/dbus-sysdeps.h
+++ b/dbus/dbus-sysdeps.h
@@ -3,6 +3,7 @@
*
* Copyright (C) 2002, 2003 Red Hat, Inc.
* Copyright (C) 2003 CodeFactory AB
+ * Copyright (C) 2011 Nokia Corp.
*
* Licensed under the Academic Free License version 2.1
*
@@ -529,6 +530,15 @@ void _dbus_request_file_descriptor_limit (unsigned int limit);
const char *
_dbus_replace_install_prefix (const char *configure_time_path);
+/*
+ * Reset the some of the current process' attributes.
+ * To be used before exec()uting a service.
+ *
+ * For example it sets OOM protection to 0.
+ */
+void
+_dbus_reset_process_attributes (void);
+
/** @} */
DBUS_END_DECLS