diff options
author | Jouke Witteveen <j.witteveen@gmail.com> | 2017-08-02 17:08:31 +0200 |
---|---|---|
committer | Jouke Witteveen <j.witteveen@gmail.com> | 2017-08-04 11:25:49 +0200 |
commit | 01f989c66253ea923679ffddf266ea13339c295b (patch) | |
tree | 2e1b60f2f291a41521b3ea704e3bcca973a3409a /src | |
parent | ad6fc5bbaef13cc0faee65ab2dad963ee36b3529 (diff) | |
download | systemd-01f989c66253ea923679ffddf266ea13339c295b.tar.gz |
process-util: update the end pointer of the process name on rename (#6492)
We only updated the end pointer when allocating new memory, i.e. on the first
call to rename_process.
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/process-util.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/src/basic/process-util.c b/src/basic/process-util.c index f5bd6c9487..2b23ac36c0 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -312,19 +312,18 @@ int rename_process(const char name[]) { /* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but * has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at * the end. This is the best option for changing /proc/self/cmdline. */ - if (mm_size < l+1) { + + /* 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 + * PR_SET_MM_ARG_{START,END} fails with EPERM later on anyway. After all geteuid() is dead cheap to call, but + * mmap() is not. */ + if (geteuid() != 0) + log_debug("Skipping PR_SET_MM, as we don't have privileges."); + else if (mm_size < l+1) { size_t nn_size; char *nn; - /* Let's not bother with this if we don't have euid == 0. Strictly speaking if people do weird stuff - * with capabilities this could work even for euid != 0, but our own code generally doesn't do that, - * hence let's use this as quick bypass check, to avoid calling mmap() if PR_SET_MM_ARG_START fails - * with EPERM later on anyway. After all geteuid() is dead cheap to call, but mmap() is not. */ - if (geteuid() != 0) { - log_debug("Skipping PR_SET_MM_ARG_START, as we don't have privileges."); - goto use_saved_argv; - } - nn_size = PAGE_ALIGN(l+1); nn = mmap(NULL, nn_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (nn == MAP_FAILED) { @@ -351,9 +350,14 @@ int rename_process(const char name[]) { mm = nn; mm_size = nn_size; - } else + } else { strncpy(mm, name, mm_size); + /* Update the end pointer, continuing regardless of any failure. */ + if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) mm + l + 1, 0, 0) < 0) + log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m"); + } + use_saved_argv: /* Fourth step: in all cases we'll also update the original argv[], so that our own code gets it right too if * it still looks here */ |