diff options
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/linux/suid/process_util_linux.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/sandbox/linux/suid/process_util_linux.c b/sandbox/linux/suid/process_util_linux.c index 7b31274..17453de 100644 --- a/sandbox/linux/suid/process_util_linux.c +++ b/sandbox/linux/suid/process_util_linux.c @@ -5,6 +5,8 @@ // The following is the C version of code from base/process_utils_linux.cc. // We shouldn't link against C++ code in a setuid binary. +#define _GNU_SOURCE // needed for O_DIRECTORY + #include "process_util.h" #include <fcntl.h> @@ -21,24 +23,33 @@ bool AdjustOOMScore(pid_t process, int score) { if (score < 0 || score > 15) return false; - char oom_adj[35]; // "/proc/" + log_10(2**64) + "/oom_adj\0" - // 6 + 20 + 9 = 35 + char oom_adj[27]; // "/proc/" + log_10(2**64) + "\0" + // 6 + 20 + 1 = 27 snprintf(oom_adj, sizeof(oom_adj), "/proc/%" PRIdMAX, (intmax_t)process); + const int dirfd = open(oom_adj, O_RDONLY | O_DIRECTORY); + if (dirfd < 0) + return false; + struct stat statbuf; - if (stat(oom_adj, &statbuf) < 0) + if (fstat(dirfd, &statbuf) < 0) { + close(dirfd); return false; - if (getuid() != statbuf.st_uid) + } + if (getuid() != statbuf.st_uid) { + close(dirfd); return false; + } + + const int fd = openat(dirfd, "oom_adj", O_WRONLY); + close(dirfd); - strcat(oom_adj, "/oom_adj"); - int fd = open(oom_adj, O_WRONLY); if (fd < 0) return false; char buf[3]; // 0 <= |score| <= 15; snprintf(buf, sizeof(buf), "%d", score); - ssize_t len = strlen(buf); + size_t len = strlen(buf); ssize_t bytes_written = write(fd, buf, len); close(fd); |