Merge pull request #8125 from poettering/cgroups-migrate

Trivial merge conflict resolved locally.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2018-02-15 16:15:45 +01:00
26 changed files with 888 additions and 299 deletions
+4
View File
@@ -1368,4 +1368,8 @@ struct fib_rule_uid_range {
#define FALLOC_FL_PUNCH_HOLE 0x02
#endif
#ifndef PF_KTHREAD
#define PF_KTHREAD 0x00200000
#endif
#include "missing_syscall.h"
+44 -20
View File
@@ -398,37 +398,61 @@ use_saved_argv:
}
int is_kernel_thread(pid_t pid) {
_cleanup_free_ char *line = NULL;
unsigned long long flags;
size_t l, i;
const char *p;
size_t count;
char c;
bool eof;
FILE *f;
char *q;
int r;
if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */
return 0;
if (!pid_is_valid(pid))
return -EINVAL;
assert(pid > 1);
p = procfs_file_alloca(pid, "stat");
r = read_one_line_file(p, &line);
if (r == -ENOENT)
return -ESRCH;
if (r < 0)
return r;
p = procfs_file_alloca(pid, "cmdline");
f = fopen(p, "re");
if (!f) {
if (errno == ENOENT)
return -ESRCH;
return -errno;
/* Skip past the comm field */
q = strrchr(line, ')');
if (!q)
return -EINVAL;
q++;
/* Skip 6 fields to reach the flags field */
for (i = 0; i < 6; i++) {
l = strspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q += l;
l = strcspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q += l;
}
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
/* Skip preceeding whitespace */
l = strspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q += l;
count = fread(&c, 1, 1, f);
eof = feof(f);
fclose(f);
/* Truncate the rest */
l = strcspn(q, WHITESPACE);
if (l < 1)
return -EINVAL;
q[l] = 0;
/* Kernel threads have an empty cmdline */
r = safe_atollu(q, &flags);
if (r < 0)
return r;
if (count <= 0)
return eof ? 1 : -errno;
return 0;
return !!(flags & PF_KTHREAD);
}
int get_process_capeff(pid_t pid, char **capeff) {
+20 -5
View File
@@ -197,6 +197,25 @@ int get_user_creds(
return 0;
}
static inline bool is_nologin_shell(const char *shell) {
return PATH_IN_SET(shell,
/* 'nologin' is the friendliest way to disable logins for a user account. It prints a nice
* message and exits. Different distributions place the binary at different places though,
* hence let's list them all. */
"/bin/nologin",
"/sbin/nologin",
"/usr/bin/nologin",
"/usr/sbin/nologin",
/* 'true' and 'false' work too for the same purpose, but are less friendly as they don't do
* any message printing. Different distributions place the binary at various places but at
* least not in the 'sbin' directory. */
"/bin/false",
"/usr/bin/false",
"/bin/true",
"/usr/bin/true");
}
int get_user_creds_clean(
const char **username,
uid_t *uid, gid_t *gid,
@@ -212,11 +231,7 @@ int get_user_creds_clean(
return r;
if (shell &&
(isempty(*shell) || PATH_IN_SET(*shell,
"/bin/nologin",
"/sbin/nologin",
"/usr/bin/nologin",
"/usr/sbin/nologin")))
(isempty(*shell) || is_nologin_shell(*shell)))
*shell = NULL;
if (home &&