aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic/process-util.c')
-rw-r--r--src/basic/process-util.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 5b700df33..ebf613b9d 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;