Merge pull request #8125 from poettering/cgroups-migrate
Trivial merge conflict resolved locally.
This commit is contained in:
@@ -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
@@ -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
@@ -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 &&
|
||||
|
||||
Reference in New Issue
Block a user