X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-sysdeps-util-unix.c;h=26fcb5bc99cf7ef48e3484baa25181210c456167;hb=1962bd7b478b21ae054b836f41e944f2a45f6621;hp=5d08c0ba49be87475a624a0edcd15f268f76fabe;hpb=2e8c59d9cc8762d8f75994675cd19247534b66c5;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index 5d08c0b..26fcb5b 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -406,23 +406,15 @@ _dbus_rlimit_save_fd_limit (DBusError *error) return self; } +/* Enough fds that we shouldn't run out, even if several uids work + * together to carry out a denial-of-service attack. This happens to be + * the same number that systemd < 234 would normally use. */ +#define ENOUGH_FDS 65536 + dbus_bool_t -_dbus_rlimit_raise_fd_limit_if_privileged (unsigned int desired, - DBusError *error) +_dbus_rlimit_raise_fd_limit (DBusError *error) { - struct rlimit lim; - - /* No point to doing this practically speaking - * if we're not uid 0. We expect the system - * bus to use this before we change UID, and - * the session bus takes the Linux default, - * currently 1024 for cur and 4096 for max. - */ - if (getuid () != 0) - { - /* not an error, we're probably the session bus */ - return TRUE; - } + struct rlimit old, lim; if (getrlimit (RLIMIT_NOFILE, &lim) < 0) { @@ -431,22 +423,43 @@ _dbus_rlimit_raise_fd_limit_if_privileged (unsigned int desired, return FALSE; } - if (lim.rlim_cur == RLIM_INFINITY || lim.rlim_cur >= desired) + old = lim; + + if (getuid () == 0) { - /* not an error, everything is fine */ - return TRUE; + /* We are privileged, so raise the soft limit to at least + * ENOUGH_FDS, and the hard limit to at least the desired soft + * limit. This assumes we can exercise CAP_SYS_RESOURCE on Linux, + * or other OSs' equivalents. */ + if (lim.rlim_cur != RLIM_INFINITY && + lim.rlim_cur < ENOUGH_FDS) + lim.rlim_cur = ENOUGH_FDS; + + if (lim.rlim_max != RLIM_INFINITY && + lim.rlim_max < lim.rlim_cur) + lim.rlim_max = lim.rlim_cur; } - /* Ignore "maximum limit", assume we have the "superuser" - * privileges. On Linux this is CAP_SYS_RESOURCE. - */ - lim.rlim_cur = lim.rlim_max = desired; + /* Raise the soft limit to match the hard limit, which we can do even + * if we are unprivileged. In particular, systemd >= 240 will normally + * set rlim_cur to 1024 and rlim_max to 512*1024, recent Debian + * versions end up setting rlim_cur to 1024 and rlim_max to 1024*1024, + * and older and non-systemd Linux systems would typically set rlim_cur + * to 1024 and rlim_max to 4096. */ + if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max) + lim.rlim_cur = lim.rlim_max; + + /* Early-return if there is nothing to do. */ + if (lim.rlim_max == old.rlim_max && + lim.rlim_cur == old.rlim_cur) + return TRUE; if (setrlimit (RLIMIT_NOFILE, &lim) < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), - "Failed to set fd limit to %u: %s", - desired, _dbus_strerror (errno)); + "Failed to set fd limit to %lu: %s", + (unsigned long) lim.rlim_cur, + _dbus_strerror (errno)); return FALSE; } @@ -485,8 +498,7 @@ _dbus_rlimit_save_fd_limit (DBusError *error) } dbus_bool_t -_dbus_rlimit_raise_fd_limit_if_privileged (unsigned int desired, - DBusError *error) +_dbus_rlimit_raise_fd_limit (DBusError *error) { fd_limit_not_supported (error); return FALSE; @@ -548,7 +560,7 @@ dbus_bool_t _dbus_user_at_console (const char *username, DBusError *error) { - +#ifdef DBUS_CONSOLE_AUTH_DIR DBusString u, f; dbus_bool_t result; @@ -579,6 +591,9 @@ _dbus_user_at_console (const char *username, _dbus_string_free (&f); return result; +#else + return FALSE; +#endif } @@ -1509,3 +1524,43 @@ _dbus_get_session_config_file (DBusString *str) return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE); } + +#ifdef DBUS_ENABLE_EMBEDDED_TESTS + +/* + * Set uid to a machine-readable authentication identity (numeric Unix + * uid or ConvertSidToStringSid-style Windows SID) that is likely to exist, + * and differs from the identity of the current process. + * + * @param uid Populated with a machine-readable authentication identity + * on success + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_test_append_different_uid (DBusString *uid) +{ + if (geteuid () == 0) + return _dbus_string_append (uid, "65534"); + else + return _dbus_string_append (uid, "0"); +} + +/* + * Set uid to a human-readable authentication identity (login name) + * that is likely to exist, and differs from the identity of the current + * process. This function currently only exists on Unix platforms. + * + * @param uid Populated with a machine-readable authentication identity + * on success + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_test_append_different_username (DBusString *username) +{ + if (geteuid () == 0) + return _dbus_string_append (username, "nobody"); + else + return _dbus_string_append (username, "root"); +} + +#endif