diff options
| author | Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> | 2011-01-24 15:00:00 +0000 |
|---|---|---|
| committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-02-25 13:16:04 +0000 |
| commit | e0bc10ec873f9830d01c70b34095413033d97456 (patch) | |
| tree | ab8923adec40dc26584e09f48a34670a39326e52 | |
| parent | de99ea078f0b2e31d1db374716bb44899ceb4c55 (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.c | 3 | ||||
| -rw-r--r-- | bus/activation.c | 21 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps-util-unix.c | 33 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps-util-win.c | 13 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps.h | 10 |
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 |
