From: Yu Watanabe Date: Thu, 23 Feb 2023 02:39:42 +0000 (+0900) Subject: sd-journal: fix memleak and freeing invalid pointers X-Git-Tag: v254-rc1~1174^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5648ebaf403dd2614a7cc72e892f4d29eaca46ef;p=thirdparty%2Fsystemd.git sd-journal: fix memleak and freeing invalid pointers This also makes - use GREEDY_REALLOC() or GREEDY_REALLOC0(), - use CLEANUP_ARRAY() macro. --- diff --git a/src/libsystemd/sd-journal/journal-send.c b/src/libsystemd/sd-journal/journal-send.c index 00c53f6d5b8..c360d0e1826 100644 --- a/src/libsystemd/sd-journal/journal-send.c +++ b/src/libsystemd/sd-journal/journal-send.c @@ -148,93 +148,64 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) { return sd_journal_sendv(iov, 2); } -_printf_(1, 0) static int fill_iovec_sprintf(const char *format, va_list ap, int extra, struct iovec **_iov) { +_printf_(1, 0) static int fill_iovec_sprintf(const char *format, va_list ap, size_t extra, struct iovec **ret_iov, size_t *ret_n_iov) { PROTECT_ERRNO; - int r, n = 0, i = 0, j; struct iovec *iov = NULL; + size_t n = 0; - assert(_iov); + assert(ret_iov); + assert(ret_n_iov); if (extra > 0) { - n = MAX(extra * 2, extra + 4); - iov = malloc0(n * sizeof(struct iovec)); - if (!iov) { - r = -ENOMEM; - goto fail; - } + if (!GREEDY_REALLOC0(iov, extra)) + return -ENOMEM; - i = extra; + n = extra; } + CLEANUP_ARRAY(iov, n, iovec_array_free); + while (format) { - struct iovec *c; - char *buffer; + _cleanup_free_ char *buffer = NULL; va_list aq; - if (i >= n) { - n = MAX(i*2, 4); - c = reallocarray(iov, n, sizeof(struct iovec)); - if (!c) { - r = -ENOMEM; - goto fail; - } - - iov = c; - } - va_copy(aq, ap); if (vasprintf(&buffer, format, aq) < 0) { va_end(aq); - r = -ENOMEM; - goto fail; + return -ENOMEM; } va_end(aq); VA_FORMAT_ADVANCE(format, ap); - - (void) strstrip(buffer); /* strip trailing whitespace, keep prefixing whitespace */ - - iov[i++] = IOVEC_MAKE_STRING(buffer); - format = va_arg(ap, char *); - } - - *_iov = iov; - return i; + if (!GREEDY_REALLOC(iov, n + 1)) + return -ENOMEM; -fail: - for (j = 0; j < i; j++) - free(iov[j].iov_base); - - free(iov); + /* strip trailing whitespace, keep prefixing whitespace */ + iov[n++] = IOVEC_MAKE_STRING(delete_trailing_chars(TAKE_PTR(buffer), NULL)); + } - return r; + *ret_iov = TAKE_PTR(iov); + *ret_n_iov = n; + return 0; } _public_ int sd_journal_send(const char *format, ...) { - int r, i, j; - va_list ap; struct iovec *iov = NULL; + size_t n_iov = 0; + va_list ap; + int r; + + CLEANUP_ARRAY(iov, n_iov, iovec_array_free); va_start(ap, format); - i = fill_iovec_sprintf(format, ap, 0, &iov); + r = fill_iovec_sprintf(format, ap, 0, &iov, &n_iov); va_end(ap); + if (r < 0) + return r; - if (_unlikely_(i < 0)) { - r = i; - goto finish; - } - - r = sd_journal_sendv(iov, i); - -finish: - for (j = 0; j < i; j++) - free(iov[j].iov_base); - - free(iov); - - return r; + return sd_journal_sendv(iov, n_iov); } _public_ int sd_journal_sendv(const struct iovec *iov, int n) { @@ -529,19 +500,19 @@ _public_ int sd_journal_printv_with_location(int priority, const char *file, con } _public_ int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) { - _cleanup_free_ struct iovec *iov = NULL; - int r, i, j; + struct iovec *iov = NULL; + size_t n_iov = 0; va_list ap; char *f; + int r; + + CLEANUP_ARRAY(iov, n_iov, iovec_array_free); va_start(ap, format); - i = fill_iovec_sprintf(format, ap, 3, &iov); + r = fill_iovec_sprintf(format, ap, 3, &iov, &n_iov); va_end(ap); - - if (_unlikely_(i < 0)) { - r = i; - goto finish; - } + if (r < 0) + return r; ALLOCA_CODE_FUNC(f, func); @@ -549,11 +520,9 @@ _public_ int sd_journal_send_with_location(const char *file, const char *line, c iov[1] = IOVEC_MAKE_STRING(line); iov[2] = IOVEC_MAKE_STRING(f); - r = sd_journal_sendv(iov, i); + r = sd_journal_sendv(iov, n_iov); -finish: - for (j = 3; j < i; j++) - free(iov[j].iov_base); + iov[0] = iov[1] = iov[2] = IOVEC_NULL; return r; }