From: Lennart Poettering Date: Mon, 17 Dec 2018 10:23:15 +0000 (+0100) Subject: process-util: make get_process_environ() safer X-Git-Tag: v240~23^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2a7797e964e5b6a0f305b00073e2b06a195d0b15;p=thirdparty%2Fsystemd.git process-util: make get_process_environ() safer Let's add a size limit, and let's use safe_fgetc(). --- diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 5b700df33a9..ebf613b9db2 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -600,12 +600,14 @@ int get_process_root(pid_t pid, char **root) { return get_process_link_contents(p, root); } +#define ENVIRONMENT_BLOCK_MAX (5U*1024U*1024U) + int get_process_environ(pid_t pid, char **env) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *outcome = NULL; - int c; - const char *p; size_t allocated = 0, sz = 0; + const char *p; + int r; assert(pid >= 0); assert(env); @@ -621,23 +623,28 @@ int get_process_environ(pid_t pid, char **env) { (void) __fsetlocking(f, FSETLOCKING_BYCALLER); - while ((c = fgetc(f)) != EOF) { + for (;;) { + char c; + + if (sz >= ENVIRONMENT_BLOCK_MAX) + return -ENOBUFS; + if (!GREEDY_REALLOC(outcome, allocated, sz + 5)) return -ENOMEM; + r = safe_fgetc(f, &c); + if (r < 0) + return r; + if (r == 0) + break; + if (c == '\0') outcome[sz++] = '\n'; else sz += cescape_char(c, outcome + sz); } - if (!outcome) { - outcome = strdup(""); - if (!outcome) - return -ENOMEM; - } else - outcome[sz] = '\0'; - + outcome[sz] = '\0'; *env = TAKE_PTR(outcome); return 0;