diff options
author | Topi Miettinen <toiwoton@gmail.com> | 2020-05-23 17:00:41 +0300 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2020-05-24 22:54:17 +0200 |
commit | cc1c85fbc3e3c09c73421e370dfbfbe4ac3d9449 (patch) | |
tree | f25b5826330d34388b2071c6e277a56b2316fcf4 | |
parent | 6a220cdb0b7d5ed787e4bfabc252fc5435f276eb (diff) | |
download | systemd-cc1c85fbc3e3c09c73421e370dfbfbe4ac3d9449.tar.gz |
login: limit nr_inodes for /run/user/$UID
Limit number of inodes for tmpfs mounts on /run/user/$UID. Default is
RuntimeDirectorySize= divided by 4096.
-rw-r--r-- | man/logind.conf.xml | 13 | ||||
-rw-r--r-- | man/org.freedesktop.login1.xml | 7 | ||||
-rw-r--r-- | src/login/logind-core.c | 1 | ||||
-rw-r--r-- | src/login/logind-dbus.c | 1 | ||||
-rw-r--r-- | src/login/logind-gperf.gperf | 1 | ||||
-rw-r--r-- | src/login/logind.conf.in | 1 | ||||
-rw-r--r-- | src/login/logind.h | 1 | ||||
-rw-r--r-- | src/login/user-runtime-dir.c | 24 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.service | 1 |
9 files changed, 40 insertions, 10 deletions
diff --git a/man/logind.conf.xml b/man/logind.conf.xml index 4cbfd09cbf..b00daf366d 100644 --- a/man/logind.conf.xml +++ b/man/logind.conf.xml @@ -305,6 +305,19 @@ </varlistentry> <varlistentry> + <term><varname>RuntimeDirectoryInodesMax=</varname></term> + + <listitem><para>Sets the limit on number of inodes for the + <varname>$XDG_RUNTIME_DIR</varname> runtime directory for each + user who logs in. Takes a number, optionally suffixed with the + usual K, G, M, and T suffixes, to the base 1024 (IEC). + Defaults to <varname>RuntimeDirectorySize=</varname> divided + by 4096. Note that this size is a safety limit only. + As each runtime directory is a tmpfs file system, it will + only consume as much 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 diff --git a/man/org.freedesktop.login1.xml b/man/org.freedesktop.login1.xml index 44ad033752..0292288d3a 100644 --- a/man/org.freedesktop.login1.xml +++ b/man/org.freedesktop.login1.xml @@ -217,6 +217,8 @@ node /org/freedesktop/login1 { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly t RuntimeDirectorySize = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly t RuntimeDirectoryInodesMax = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly t InhibitorsMax = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly t NCurrentInhibitors = ...; @@ -425,6 +427,8 @@ node /org/freedesktop/login1 { <variablelist class="dbus-property" generated="True" extra-ref="RuntimeDirectorySize"/> + <variablelist class="dbus-property" generated="True" extra-ref="RuntimeDirectoryInodesMax"/> + <variablelist class="dbus-property" generated="True" extra-ref="InhibitorsMax"/> <variablelist class="dbus-property" generated="True" extra-ref="NCurrentInhibitors"/> @@ -623,7 +627,8 @@ node /org/freedesktop/login1 { <varname>HandleLidSwitchExternalPower</varname>, <varname>HandleLidSwitchDocked</varname>, <varname>IdleActionUSec</varname>, <varname>HoldoffTimeoutUSec</varname>, <varname>RemoveIPC</varname>, <varname>RuntimeDirectorySize</varname>, - <varname>InhibitorsMax</varname>, and <varname>SessionsMax</varname>. + <varname>RuntimeDirectoryInodesMax</varname>, <varname>InhibitorsMax</varname>, and + <varname>SessionsMax</varname>. </para> <para>The <varname>IdleHint</varname> property reflects the idle hint state of the system. If the diff --git a/src/login/logind-core.c b/src/login/logind-core.c index a9006d746a..c160f546bc 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -55,6 +55,7 @@ void manager_reset_config(Manager *m) { m->idle_action = HANDLE_IGNORE; m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */ + m->runtime_dir_inodes = DIV_ROUND_UP(m->runtime_dir_size, 4096); /* 4k per inode */ m->sessions_max = 8192; m->inhibitors_max = 8192; diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 451fe28754..a88605232c 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -3359,6 +3359,7 @@ static const sd_bus_vtable manager_vtable[] = { SD_BUS_PROPERTY("OnExternalPower", "b", property_get_on_external_power, 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", NULL, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RuntimeDirectoryInodesMax", "t", NULL, offsetof(Manager, runtime_dir_inodes), 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_hashmap_size, offsetof(Manager, inhibitors), 0), SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf index 983795da40..73d96ff436 100644 --- a/src/login/logind-gperf.gperf +++ b/src/login/logind-gperf.gperf @@ -38,6 +38,7 @@ Login.HoldoffTimeoutSec, config_parse_sec, 0, offse Login.IdleAction, config_parse_handle_action, 0, offsetof(Manager, idle_action) Login.IdleActionSec, config_parse_sec, 0, offsetof(Manager, idle_action_usec) Login.RuntimeDirectorySize, config_parse_tmpfs_size, 0, offsetof(Manager, runtime_dir_size) +Login.RuntimeDirectoryInodesMax, config_parse_uint64, 0, offsetof(Manager, runtime_dir_inodes) 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) diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in index 1029e29bc7..ed1084b06e 100644 --- a/src/login/logind.conf.in +++ b/src/login/logind.conf.in @@ -32,6 +32,7 @@ #IdleAction=ignore #IdleActionSec=30min #RuntimeDirectorySize=10% +#RuntimeDirectoryInodes=400k #RemoveIPC=yes #InhibitorsMax=8192 #SessionsMax=8192 diff --git a/src/login/logind.h b/src/login/logind.h index d3f5b28078..e1d57277fa 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -120,6 +120,7 @@ struct Manager { sd_event_source *lid_switch_ignore_event_source; uint64_t runtime_dir_size; + uint64_t runtime_dir_inodes; uint64_t sessions_max; uint64_t inhibitors_max; }; diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c index 1f98898b69..4055c910c2 100644 --- a/src/login/user-runtime-dir.c +++ b/src/login/user-runtime-dir.c @@ -22,7 +22,7 @@ #include "strv.h" #include "user-util.h" -static int acquire_runtime_dir_size(uint64_t *ret) { +static int acquire_runtime_dir_properties(uint64_t *size, uint64_t *inodes) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; @@ -31,10 +31,14 @@ static int acquire_runtime_dir_size(uint64_t *ret) { if (r < 0) return log_error_errno(r, "Failed to connect to system bus: %m"); - r = sd_bus_get_property_trivial(bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "RuntimeDirectorySize", &error, 't', ret); + r = sd_bus_get_property_trivial(bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "RuntimeDirectorySize", &error, 't', size); if (r < 0) return log_error_errno(r, "Failed to acquire runtime directory size: %s", bus_error_message(&error, r)); + r = sd_bus_get_property_trivial(bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "RuntimeDirectoryInodesMax", &error, 't', inodes); + if (r < 0) + return log_error_errno(r, "Failed to acquire number of inodes for runtime directory: %s", bus_error_message(&error, r)); + return 0; } @@ -42,7 +46,8 @@ static int user_mkdir_runtime_path( const char *runtime_path, uid_t uid, gid_t gid, - uint64_t runtime_dir_size) { + uint64_t runtime_dir_size, + uint64_t runtime_dir_inodes) { int r; @@ -58,14 +63,15 @@ static int user_mkdir_runtime_path( if (path_is_mount_point(runtime_path, NULL, 0) >= 0) log_debug("%s is already a mount point", runtime_path); else { - char options[sizeof("mode=0700,uid=,gid=,size=,smackfsroot=*") + char options[sizeof("mode=0700,uid=,gid=,size=,nr_inodes=,smackfsroot=*") + DECIMAL_STR_MAX(uid_t) + DECIMAL_STR_MAX(gid_t) + + DECIMAL_STR_MAX(uint64_t) + DECIMAL_STR_MAX(uint64_t)]; xsprintf(options, - "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%" PRIu64 "%s", - uid, gid, runtime_dir_size, + "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%" PRIu64 ",nr_inodes=%" PRIu64 "%s", + uid, gid, runtime_dir_size, runtime_dir_inodes, mac_smack_use() ? ",smackfsroot=*" : ""); (void) mkdir_label(runtime_path, 0700); @@ -127,7 +133,7 @@ static int user_remove_runtime_path(const char *runtime_path) { static int do_mount(const char *user) { char runtime_path[sizeof("/run/user") + DECIMAL_STR_MAX(uid_t)]; - uint64_t runtime_dir_size; + uint64_t runtime_dir_size, runtime_dir_inodes; uid_t uid; gid_t gid; int r; @@ -140,14 +146,14 @@ static int do_mount(const char *user) { : "Failed to look up user \"%s\": %m", user); - r = acquire_runtime_dir_size(&runtime_dir_size); + r = acquire_runtime_dir_properties(&runtime_dir_size, &runtime_dir_inodes); if (r < 0) return r; xsprintf(runtime_path, "/run/user/" UID_FMT, uid); log_debug("Will mount %s owned by "UID_FMT":"GID_FMT, runtime_path, uid, gid); - return user_mkdir_runtime_path(runtime_path, uid, gid, runtime_dir_size); + return user_mkdir_runtime_path(runtime_path, uid, gid, runtime_dir_size, runtime_dir_inodes); } static int do_umount(const char *user) { diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service index 6fa96e1d58..048bd34e9e 100644 --- a/test/fuzz/fuzz-unit-file/directives.service +++ b/test/fuzz/fuzz-unit-file/directives.service @@ -865,6 +865,7 @@ RestrictNamespaces= RestrictRealtime= RestrictSUIDSGID= RuntimeDirectory= +RuntimeDirectoryInodesMax= RuntimeDirectoryMode= RuntimeDirectoryPreserve= RuntimeDirectorySize= |