summaryrefslogtreecommitdiff
path: root/src/basic/process-util.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-05-22 09:23:31 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-05-26 10:28:59 +0200
commitc55104ce58833d1382ad7da00e1866d36a0566b1 (patch)
tree3d95510c4bbbfc1e6e826d083feb4eb06c86aa42 /src/basic/process-util.c
parentad4f7f6747637288371263e550e7d3dc6630e6c0 (diff)
downloadsystemd-c55104ce58833d1382ad7da00e1866d36a0566b1.tar.gz
basic/process-util: only try PR_SET_MM once
userwork wants to update the title many times, and a strace is full of attempts that fail the same way: [pid 21765] prctl(PR_SET_NAME, "systemd-userwor"...) = 0 [pid 21765] geteuid() = 0 [pid 21765] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fedce329000 [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_START, 0x7fedce329000, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_END, 0x7fedce32901d, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] munmap(0x7fedce329000, 4096) = 0 [pid 21765] accept4(3, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EAGAIN (Resource temporarily unavailable) [pid 21765] prctl(PR_SET_NAME, "systemd-userwor"...) = 0 [pid 21765] geteuid() = 0 [pid 21765] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fedce329000 [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_START, 0x7fedce329000, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_END, 0x7fedce329020, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] munmap(0x7fedce329000, 4096) = 0 [pid 21765] prctl(PR_SET_NAME, "systemd-userwor"...) = 0 [pid 21765] geteuid() = 0 [pid 21765] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fedce329000 [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_START, 0x7fedce329000, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_END, 0x7fedce32901d, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] munmap(0x7fedce329000, 4096) = 0 [pid 21765] accept4(3, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EAGAIN (Resource temporarily unavailable) [pid 21765] prctl(PR_SET_NAME, "systemd-userwor"...) = 0 [pid 21765] geteuid() = 0 [pid 21765] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fedce329000 [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_START, 0x7fedce329000, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_END, 0x7fedce329020, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] munmap(0x7fedce329000, 4096) = 0 [pid 21765] prctl(PR_SET_NAME, "systemd-userwor"...) = 0 [pid 21765] geteuid() = 0 [pid 21765] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fedce329000 [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_START, 0x7fedce329000, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_END, 0x7fedce32901d, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] munmap(0x7fedce329000, 4096) = 0 [pid 21765] accept4(3, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EAGAIN (Resource temporarily unavailable) [pid 21765] prctl(PR_SET_NAME, "systemd-userwor"...) = 0 [pid 21765] geteuid() = 0 [pid 21765] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fedce329000 [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_START, 0x7fedce329000, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] prctl(PR_SET_MM, PR_SET_MM_ARG_END, 0x7fedce329020, 0, 0) = -1 EPERM (Operation not permitted) [pid 21765] munmap(0x7fedce329000, 4096) = 0 If we get a permission error, don't try again.
Diffstat (limited to 'src/basic/process-util.c')
-rw-r--r--src/basic/process-util.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index c96158ae5c..8cb229ca09 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -207,6 +207,12 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
}
static int update_argv(const char name[], size_t l) {
+ static int can_do = -1;
+
+ if (can_do == 0)
+ return 0;
+ can_do = false; /* We'll set it to true only if the whole process works */
+
/* Let's not bother with this if we don't have euid == 0. Strictly speaking we should check for the
* CAP_SYS_RESOURCE capability which is independent of the euid. In our own code the capability generally is
* present only for euid == 0, hence let's use this as quick bypass check, to avoid calling mmap() if
@@ -233,6 +239,9 @@ static int update_argv(const char name[], size_t l) {
/* Now, let's tell the kernel about this new memory */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) {
+ if (ERRNO_IS_PRIVILEGE(errno))
+ return log_debug_errno(errno, "PR_SET_MM_ARG_START failed: %m");
+
/* HACK: prctl() API is kind of dumb on this point. The existing end address may already be
* below the desired start address, in which case the kernel may have kicked this back due
* to a range-check failure (see linux/kernel/sys.c:validate_prctl_map() to see this in
@@ -272,6 +281,7 @@ static int update_argv(const char name[], size_t l) {
log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
}
+ can_do = true;
return 0;
}