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.
This commit is contained in:
Lennart Poettering 2016-05-04 19:40:05 +02:00
parent 6d97d3c648
commit c5a11ae268
6 changed files with 34 additions and 0 deletions

View file

@ -296,6 +296,13 @@
memory as is needed.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>InhibitorsMax=</varname></term>
<listitem><para>Controls the maximum number of concurrent inhibitors to permit. Defaults to 8192
(8K).</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>SessionsMax=</varname></term>

View file

@ -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),

View file

@ -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)

View file

@ -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;

View file

@ -32,5 +32,6 @@
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RemoveIPC=yes
#InhibitorsMax=8192
#SessionsMax=8192
#UserTasksMax=12288

View file

@ -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);