diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-03-04 21:19:02 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-03-06 09:32:18 +0100 |
commit | 5963e6f43c4f33d5255ef0fb887cdf382bd51c9e (patch) | |
tree | ec9aa21581f93831a1d3906e55d2f8881aa1023c /src/libsystemd | |
parent | 49ba1522fc585d9b9a8867de41a215dabd3b2c1a (diff) | |
download | systemd-5963e6f43c4f33d5255ef0fb887cdf382bd51c9e.tar.gz |
sd-bus: fix memstream buffer extraction
I'm getting the following error under valgrind:
==305970== Invalid free() / delete / delete[] / realloc()
==305970== at 0x483E9F1: free (vg_replace_malloc.c:538)
==305970== by 0x4012CD: mfree (alloc-util.h:48)
==305970== by 0x4012EF: freep (alloc-util.h:83)
==305970== by 0x4017F4: LLVMFuzzerTestOneInput (fuzz-bus-match.c:58)
==305970== by 0x401A58: main (fuzz-main.c:39)
==305970== Address 0x59972f0 is 0 bytes inside a block of size 8,192 free'd
==305970== at 0x483FCE4: realloc (vg_replace_malloc.c:834)
==305970== by 0x4C986F7: _IO_mem_finish (in /usr/lib64/libc-2.33.so)
==305970== by 0x4C8F5E0: fclose@@GLIBC_2.2.5 (in /usr/lib64/libc-2.33.so)
==305970== by 0x49D2CDB: fclose_nointr (fd-util.c:108)
==305970== by 0x49D2D3D: safe_fclose (fd-util.c:124)
==305970== by 0x4A4BCCC: fclosep (fd-util.h:41)
==305970== by 0x4A4E00F: bus_match_to_string (bus-match.c:859)
==305970== by 0x4016C2: LLVMFuzzerTestOneInput (fuzz-bus-match.c:58)
==305970== by 0x401A58: main (fuzz-main.c:39)
==305970== Block was alloc'd at
==305970== at 0x483FAE5: calloc (vg_replace_malloc.c:760)
==305970== by 0x4C98787: open_memstream (in /usr/lib64/libc-2.33.so)
==305970== by 0x49D56D6: open_memstream_unlocked (fileio.c:97)
==305970== by 0x4A4DEC5: bus_match_to_string (bus-match.c:859)
==305970== by 0x4016C2: LLVMFuzzerTestOneInput (fuzz-bus-match.c:58)
==305970== by 0x401A58: main (fuzz-main.c:39)
==305970==
So the fclose() which is called from _cleanup_fclose_ clearly reallocates the
buffer (maybe to save memory?). open_memstream(3) says:
The locations referred to by these pointers are updated each time the
stream is flushed (fflush(3)) and when the stream is closed (fclose(3)).
This seems to mean that we should close the stream first before grabbing the
buffer pointer.
Diffstat (limited to 'src/libsystemd')
-rw-r--r-- | src/libsystemd/sd-bus/bus-match.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/src/libsystemd/sd-bus/bus-match.c b/src/libsystemd/sd-bus/bus-match.c index db8da6ee12..2a3e7039a7 100644 --- a/src/libsystemd/sd-bus/bus-match.c +++ b/src/libsystemd/sd-bus/bus-match.c @@ -846,7 +846,7 @@ fail: } char *bus_match_to_string(struct bus_match_component *components, unsigned n_components) { - char *buffer = NULL; + _cleanup_free_ char *buffer = NULL; size_t size = 0; int r; @@ -855,7 +855,7 @@ char *bus_match_to_string(struct bus_match_component *components, unsigned n_com assert(components); - _cleanup_fclose_ FILE *f = open_memstream_unlocked(&buffer, &size); + FILE *f = open_memstream_unlocked(&buffer, &size); if (!f) return NULL; @@ -878,10 +878,10 @@ char *bus_match_to_string(struct bus_match_component *components, unsigned n_com } r = fflush_and_check(f); + safe_fclose(f); if (r < 0) return NULL; - - return buffer; + return TAKE_PTR(buffer); } int bus_match_add( |