From f392dfb5a1286184189233a84f6d6871bd4f7ade Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Wed, 24 May 2023 13:29:52 +0200 Subject: tree-wide: check memstream buffer after closing the handle When closing the FILE handle attached to a memstream, it may attempt to do a realloc() that may fail during OOM situations, in which case we are left with the buffer pointer pointing to NULL and buffer size > 0. For example: ``` #include #include #include void *realloc(void *ptr, size_t size) { return NULL; } int main(int argc, char *argv[]) { FILE *f; char *buf; size_t sz = 0; f = open_memstream(&buf, &sz); if (!f) return -ENOMEM; fputs("Hello", f); fflush(f); printf("buf: 0x%lx, sz: %lu, errno: %d\n", (unsigned long) buf, sz, errno); fclose(f); printf("buf: 0x%lx, sz: %lu, errno: %d\n", (unsigned long) buf, sz, errno); return 0; } ``` ``` $ gcc -o main main.c $ ./main buf: 0x74d4a0, sz: 5, errno: 0 buf: 0x0, sz: 5, errno: 0 ``` This might do unexpected things if the underlying code expects a valid pointer to the memstream buffer after closing the handle. Found by Nallocfuzz. --- src/oom/oomd-manager.c | 3 +++ src/oom/oomd-util.c | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'src/oom') diff --git a/src/oom/oomd-manager.c b/src/oom/oomd-manager.c index 08a29ec77b..3f050cdbb2 100644 --- a/src/oom/oomd-manager.c +++ b/src/oom/oomd-manager.c @@ -847,6 +847,9 @@ int manager_get_dump_string(Manager *m, char **ret) { f = safe_fclose(f); + if (!dump) + return -ENOMEM; + *ret = TAKE_PTR(dump); return 0; } diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index 49c10b5e16..6309d2c473 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -299,6 +299,11 @@ static int dump_kill_candidates(OomdCGroupContext **sorted, int n, int dump_unti if (r < 0) return r; + f = safe_fclose(f); + + if (!dump) + return -ENOMEM; + return log_dump(LOG_INFO, dump); } -- cgit v1.2.3