From: Lennart Poettering Date: Thu, 21 Sep 2017 17:43:07 +0000 (+0200) Subject: main: bump RLIMIT_NOFILE for the root user substantially X-Git-Tag: v235~60^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fb3ae275cbd6bc17444e0816ee4c7496f2750209;p=thirdparty%2Fsystemd.git main: bump RLIMIT_NOFILE for the root user substantially On current kernels BPF_MAP_TYPE_LPM_TRIE bpf maps are charged against RLIMIT_MEMLOCK even for privileged users that have CAP_IPC_LOCK. Given that mlock() generally ignores RLIMIT_MEMLOCK if CAP_IPC_LOCK is set this appears to be an oversight in the kernel. Either way, until that's fixed, let's just bump RLIMIT_MEMLOCK for the root user considerably, as the default is quite limiting, and doesn't permit us to create more than a few TRIE maps. --- diff --git a/src/core/main.c b/src/core/main.c index 8660a31a2dd..2dfd48005b7 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1205,6 +1205,26 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) { return 0; } +static int bump_rlimit_memlock(struct rlimit *saved_rlimit) { + int r; + + assert(saved_rlimit); + assert(getuid() == 0); + + /* BPF_MAP_TYPE_LPM_TRIE bpf maps are charged against RLIMIT_MEMLOCK, even though we have CAP_IPC_LOCK which + * should normally disable such checks. We need them to implement IPAccessAllow= and IPAccessDeny=, hence let's + * bump the value high enough for the root user. */ + + if (getrlimit(RLIMIT_MEMLOCK, saved_rlimit) < 0) + return log_warning_errno(errno, "Reading RLIMIT_MEMLOCK failed, ignoring: %m"); + + r = setrlimit_closest(RLIMIT_MEMLOCK, &RLIMIT_MAKE_CONST(1024ULL*1024ULL*16ULL)); + if (r < 0) + return log_warning_errno(r, "Setting RLIMIT_MEMLOCK failed, ignoring: %m"); + + return 0; +} + static void test_usr(void) { /* Check that /usr is not a separate fs */ @@ -1388,7 +1408,7 @@ int main(int argc, char *argv[]) { bool queue_default_job = false; bool empty_etc = false; char *switch_root_dir = NULL, *switch_root_init = NULL; - struct rlimit saved_rlimit_nofile = RLIMIT_MAKE_CONST(0); + struct rlimit saved_rlimit_nofile = RLIMIT_MAKE_CONST(0), saved_rlimit_memlock = RLIMIT_MAKE_CONST((rlim_t) -1); const char *error_message = NULL; #ifdef HAVE_SYSV_COMPAT @@ -1815,9 +1835,11 @@ int main(int argc, char *argv[]) { if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) log_warning_errno(errno, "Failed to make us a subreaper: %m"); - if (arg_system) + if (arg_system) { /* Bump up RLIMIT_NOFILE for systemd itself */ (void) bump_rlimit_nofile(&saved_rlimit_nofile); + (void) bump_rlimit_memlock(&saved_rlimit_memlock); + } } r = manager_new(arg_system ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, @@ -2051,6 +2073,8 @@ finish: * its child processes */ if (saved_rlimit_nofile.rlim_cur > 0) (void) setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile); + if (saved_rlimit_memlock.rlim_cur != (rlim_t) -1) + (void) setrlimit(RLIMIT_MEMLOCK, &saved_rlimit_memlock); if (switch_root_dir) { /* Kill all remaining processes from the