From c5a11ae268cf4188caf74d1acfd506a606e85967 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 4 May 2016 19:40:05 +0200 Subject: logind: enforce a limit on inhibitors we hand out For similar reasons as the recent addition of a limit on sessions. Note that we don't enforce a limit on inhibitors per-user currently, but there's an implicit one, since each inhibitor takes up one fd, and fds are limited via RLIMIT_NOFILE, and the limit on the number of processes per user. --- man/logind.conf.xml | 7 +++++++ src/login/logind-dbus.c | 23 +++++++++++++++++++++++ src/login/logind-gperf.gperf | 1 + src/login/logind.c | 1 + src/login/logind.conf.in | 1 + src/login/logind.h | 1 + 6 files changed, 34 insertions(+) diff --git a/man/logind.conf.xml b/man/logind.conf.xml index 405dcf9041..fe92277a1f 100644 --- a/man/logind.conf.xml +++ b/man/logind.conf.xml @@ -296,6 +296,13 @@ memory as is needed. + + InhibitorsMax= + + Controls the maximum number of concurrent inhibitors to permit. Defaults to 8192 + (8K). + + SessionsMax= diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index d249bff2d9..0a84d75e24 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -283,6 +283,24 @@ static int property_get_current_sessions( return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->sessions)); } +static int property_get_current_inhibitors( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + Manager *m = userdata; + + assert(bus); + assert(reply); + assert(m); + + return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->inhibitors)); +} + static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) { _cleanup_free_ char *p = NULL; Manager *m = userdata; @@ -2463,6 +2481,9 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error if (r < 0) return r; + if (hashmap_size(m->inhibitors) >= m->inhibitors_max) + return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Maximum number of inhibitors (%" PRIu64 ") reached, refusing further inhibitors.", m->inhibitors_max); + do { id = mfree(id); @@ -2535,6 +2556,8 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0), SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RuntimeDirectorySize", "t", bus_property_get_size, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_current_inhibitors, 0, 0), SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_current_sessions, 0, 0), SD_BUS_PROPERTY("UserTasksMax", "t", NULL, offsetof(Manager, user_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf index 1d57681260..6bd08adc05 100644 --- a/src/login/logind-gperf.gperf +++ b/src/login/logind-gperf.gperf @@ -34,5 +34,6 @@ Login.IdleAction, config_parse_handle_action, 0, offsetof(Manag Login.IdleActionSec, config_parse_sec, 0, offsetof(Manager, idle_action_usec) Login.RuntimeDirectorySize, config_parse_tmpfs_size, 0, offsetof(Manager, runtime_dir_size) Login.RemoveIPC, config_parse_bool, 0, offsetof(Manager, remove_ipc) +Login.InhibitorsMax, config_parse_uint64, 0, offsetof(Manager, inhibitors_max) Login.SessionsMax, config_parse_uint64, 0, offsetof(Manager, sessions_max) Login.UserTasksMax, config_parse_uint64, 0, offsetof(Manager, user_tasks_max) diff --git a/src/login/logind.c b/src/login/logind.c index 64bd1ca582..1cbc8f9fcc 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -64,6 +64,7 @@ static void manager_reset_config(Manager *m) { m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */ m->user_tasks_max = UINT64_C(12288); m->sessions_max = UINT64_C(8192); + m->inhibitors_max = UINT64_C(8192); m->kill_user_processes = KILL_USER_PROCESSES; diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in index 6284218625..32c0844cb6 100644 --- a/src/login/logind.conf.in +++ b/src/login/logind.conf.in @@ -32,5 +32,6 @@ #IdleActionSec=30min #RuntimeDirectorySize=10% #RemoveIPC=yes +#InhibitorsMax=8192 #SessionsMax=8192 #UserTasksMax=12288 diff --git a/src/login/logind.h b/src/login/logind.h index 23c3e2963a..90431eb4b0 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -134,6 +134,7 @@ struct Manager { size_t runtime_dir_size; uint64_t user_tasks_max; uint64_t sessions_max; + uint64_t inhibitors_max; }; int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device); -- cgit v1.2.3-54-g00ecf