]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #27770 from mrc0mmand/more-nallocfuzz-shenanigans
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 25 May 2023 08:15:37 +0000 (17:15 +0900)
committerGitHub <noreply@github.com>
Thu, 25 May 2023 08:15:37 +0000 (17:15 +0900)
A couple of fixes for potential issues during OOM situations

21 files changed:
src/basic/env-file.c
src/basic/string-util.c
src/busctl/busctl.c
src/core/manager-dump.c
src/coredump/coredump.c
src/journal/journalctl.c
src/libsystemd/sd-bus/bus-introspect.c
src/libsystemd/sd-bus/bus-match.c
src/libsystemd/sd-journal/catalog.c
src/network/generator/network-generator.c
src/oom/oomd-manager.c
src/oom/oomd-util.c
src/resolve/resolved-dns-dnssec.c
src/resolve/resolved-dns-rr.c
src/resolve/resolved-manager.c
src/shared/bus-util.c
src/shared/calendarspec.c
src/shared/elf-util.c
src/shared/format-table.c
src/shared/json.c
src/shared/specifier.c

index 7b3e209ddcac6aa34dcf2a24ba6ed84287789f98..58d7b3ec359d5a949be7652807980e248d1c3641 100644 (file)
@@ -330,8 +330,7 @@ static int parse_env_file_push(
 
                 if (streq(key, k)) {
                         va_end(aq);
-                        free(*v);
-                        *v = value;
+                        free_and_replace(*v, value);
 
                         return 1;
                 }
index d4141968df34c4ad74be14c019f8704004a18926..61737ffb41b367221bef78ae804cba16abd0e728 100644 (file)
@@ -9,6 +9,7 @@
 #include "alloc-util.h"
 #include "escape.h"
 #include "extract-word.h"
+#include "fd-util.h"
 #include "fileio.h"
 #include "gunicode.h"
 #include "locale-util.h"
@@ -603,9 +604,9 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
                 STATE_CSI,
                 STATE_CSO,
         } state = STATE_OTHER;
-        char *obuf = NULL;
+        _cleanup_free_ char *obuf = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         size_t osz = 0, isz, shift[2] = {}, n_carriage_returns = 0;
-        FILE *f;
 
         assert(ibuf);
         assert(*ibuf);
@@ -713,11 +714,13 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
                 }
         }
 
-        if (fflush_and_check(f) < 0) {
-                fclose(f);
-                return mfree(obuf);
-        }
-        fclose(f);
+        if (fflush_and_check(f) < 0)
+                return NULL;
+
+        f = safe_fclose(f);
+
+        if (!obuf)
+                return NULL;
 
         free_and_replace(*ibuf, obuf);
 
index 965ded9675ecb57767fb081fb70179507b739cf8..4d69aee5eb727421de3f92c1a7a10e9d4efe50bd 100644 (file)
@@ -1072,6 +1072,9 @@ static int introspect(int argc, char **argv, void *userdata) {
 
                         mf = safe_fclose(mf);
 
+                        if (!buf)
+                                return bus_log_parse_error(ENOMEM);
+
                         z = set_get(members, &((Member) {
                                                 .type = "property",
                                                 .interface = m->interface,
index 5a92356d487e7124b9026f617350e2b4471d365c..35143ebddf479a2e6b35c570ccd7ccc760002f3e 100644 (file)
@@ -95,6 +95,9 @@ int manager_get_dump_string(Manager *m, char **patterns, char **ret) {
 
         f = safe_fclose(f);
 
+        if (!dump)
+                return -ENOMEM;
+
         *ret = TAKE_PTR(dump);
 
         return 0;
index 5fdcfa74372163d6fa0f0b3cecd8dcc0ee5f753e..a6b0d96488a77536aae71cc788baa91174b35c2d 100644 (file)
@@ -707,6 +707,9 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
         if (errno > 0)
                 return -errno;
 
+        if (!buffer)
+                return -ENOMEM;
+
         *open_fds = TAKE_PTR(buffer);
 
         return 0;
index 5f3a121ac9fef57df3c94b56c8a171090be3a7ed..e379203d5d796de7140eca3c18123a55221e7618 100644 (file)
@@ -1811,6 +1811,10 @@ static int format_journal_url(
                 return r;
 
         f = safe_fclose(f);
+
+        if (!url)
+                return -ENOMEM;
+
         *ret_url = TAKE_PTR(url);
         return 0;
 }
index 49236a8e129d3a4841b15695a38c2de56c419c98..3d4c47c6dd7618d80f42f51798930f9f6216de71 100644 (file)
@@ -268,6 +268,10 @@ int introspect_finish(struct introspect *i, char **ret) {
                 return r;
 
         i->f = safe_fclose(i->f);
+
+        if (!i->introspection)
+                return -ENOMEM;
+
         *ret = TAKE_PTR(i->introspection);
 
         return 0;
index 703b9ac038b69e57432d7fc9740a6d196c022a71..cc043abfe348edabe0e810d3acd5bfb550a0e5b4 100644 (file)
@@ -824,6 +824,7 @@ int bus_match_parse(
 
 char *bus_match_to_string(struct bus_match_component *components, size_t n_components) {
         _cleanup_free_ char *buffer = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         size_t size = 0;
         int r;
 
@@ -832,7 +833,7 @@ char *bus_match_to_string(struct bus_match_component *components, size_t n_compo
 
         assert(components);
 
-        FILE *f = open_memstream_unlocked(&buffer, &size);
+        f = open_memstream_unlocked(&buffer, &size);
         if (!f)
                 return NULL;
 
@@ -855,9 +856,11 @@ char *bus_match_to_string(struct bus_match_component *components, size_t n_compo
         }
 
         r = fflush_and_check(f);
-        safe_fclose(f);
         if (r < 0)
                 return NULL;
+
+        f = safe_fclose(f);
+
         return TAKE_PTR(buffer);
 }
 
index 7527abf636cb99756b5fc75f5cec4598b1817f54..06cf396b95901b22e50dbcf1705edacfe083f439 100644 (file)
@@ -145,7 +145,9 @@ static int finish_item(
                 char *payload, size_t payload_size) {
 
         _cleanup_free_ CatalogItem *i = NULL;
-        _cleanup_free_ char *prev = NULL, *combined = NULL;
+        _cleanup_free_ char *combined = NULL;
+        char *prev;
+        int r;
 
         assert(h);
         assert(payload);
@@ -168,19 +170,24 @@ static int finish_item(
                 if (!combined)
                         return log_oom();
 
-                if (ordered_hashmap_update(h, i, combined) < 0)
-                        return log_oom();
-                combined = NULL;
+                r = ordered_hashmap_update(h, i, combined);
+                if (r < 0)
+                        return r;
+
+                TAKE_PTR(combined);
+                free(prev);
         } else {
                 /* A new item */
                 combined = memdup(payload, payload_size + 1);
                 if (!combined)
                         return log_oom();
 
-                if (ordered_hashmap_put(h, i, combined) < 0)
-                        return log_oom();
-                i = NULL;
-                combined = NULL;
+                r = ordered_hashmap_put(h, i, combined);
+                if (r < 0)
+                        return r;
+
+                TAKE_PTR(i);
+                TAKE_PTR(combined);
         }
 
         return 0;
index 1090934bfc15e03d00e2503b4b62a1429d7f8bf8..569dcdf5114d78ee2b6f0f54bf6169d9ee293fb4 100644 (file)
@@ -1199,30 +1199,31 @@ void link_dump(Link *link, FILE *f) {
 
 int network_format(Network *network, char **ret) {
         _cleanup_free_ char *s = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         size_t sz = 0;
         int r;
 
         assert(network);
         assert(ret);
 
-        {
-                _cleanup_fclose_ FILE *f = NULL;
-
-                f = open_memstream_unlocked(&s, &sz);
-                if (!f)
-                        return -ENOMEM;
+        f = open_memstream_unlocked(&s, &sz);
+        if (!f)
+                return -ENOMEM;
 
-                network_dump(network, f);
+        network_dump(network, f);
 
-                /* Add terminating 0, so that the output buffer is a valid string. */
-                fputc('\0', f);
+        /* Add terminating 0, so that the output buffer is a valid string. */
+        fputc('\0', f);
 
-                r = fflush_and_check(f);
-        }
+        r = fflush_and_check(f);
         if (r < 0)
                 return r;
 
-        assert(s);
+        f = safe_fclose(f);
+
+        if (!s)
+                return -ENOMEM;
+
         *ret = TAKE_PTR(s);
         assert(sz > 0);
         return (int) sz - 1;
@@ -1230,30 +1231,31 @@ int network_format(Network *network, char **ret) {
 
 int netdev_format(NetDev *netdev, char **ret) {
         _cleanup_free_ char *s = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         size_t sz = 0;
         int r;
 
         assert(netdev);
         assert(ret);
 
-        {
-                _cleanup_fclose_ FILE *f = NULL;
-
-                f = open_memstream_unlocked(&s, &sz);
-                if (!f)
-                        return -ENOMEM;
+        f = open_memstream_unlocked(&s, &sz);
+        if (!f)
+                return -ENOMEM;
 
-                netdev_dump(netdev, f);
+        netdev_dump(netdev, f);
 
-                /* Add terminating 0, so that the output buffer is a valid string. */
-                fputc('\0', f);
+        /* Add terminating 0, so that the output buffer is a valid string. */
+        fputc('\0', f);
 
-                r = fflush_and_check(f);
-        }
+        r = fflush_and_check(f);
         if (r < 0)
                 return r;
 
-        assert(s);
+        f = safe_fclose(f);
+
+        if (!s)
+                return -ENOMEM;
+
         *ret = TAKE_PTR(s);
         assert(sz > 0);
         return (int) sz - 1;
@@ -1261,30 +1263,31 @@ int netdev_format(NetDev *netdev, char **ret) {
 
 int link_format(Link *link, char **ret) {
         _cleanup_free_ char *s = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         size_t sz = 0;
         int r;
 
         assert(link);
         assert(ret);
 
-        {
-                _cleanup_fclose_ FILE *f = NULL;
-
-                f = open_memstream_unlocked(&s, &sz);
-                if (!f)
-                        return -ENOMEM;
+        f = open_memstream_unlocked(&s, &sz);
+        if (!f)
+                return -ENOMEM;
 
-                link_dump(link, f);
+        link_dump(link, f);
 
-                /* Add terminating 0, so that the output buffer is a valid string. */
-                fputc('\0', f);
+        /* Add terminating 0, so that the output buffer is a valid string. */
+        fputc('\0', f);
 
-                r = fflush_and_check(f);
-        }
+        r = fflush_and_check(f);
         if (r < 0)
                 return r;
 
-        assert(s);
+        f = safe_fclose(f);
+
+        if (!s)
+                return -ENOMEM;
+
         *ret = TAKE_PTR(s);
         assert(sz > 0);
         return (int) sz - 1;
index 08a29ec77bd84ec075ecf50401ec07cc1c9c70d9..3f050cdbb29fadd4aa95b6e06dcb03511bbda0d3 100644 (file)
@@ -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;
 }
index 49c10b5e16c235d4f9860531e33a6eb76e664975..6309d2c4739907c3f81dac56e8eb91eaabb5f05f 100644 (file)
@@ -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);
 }
 
index fc076856b601d636d1b6e3095bfaaaa14c7eefef..e7c18c29a0b2e81dbb8f5e40c84d2b63f5871c55 100644 (file)
@@ -867,10 +867,14 @@ static int dnssec_rrset_serialize_sig(
         }
 
         r = fflush_and_check(f);
-        f = safe_fclose(f);  /* sig_data may be reallocated when f is closed. */
         if (r < 0)
                 return r;
 
+        f = safe_fclose(f);  /* sig_data may be reallocated when f is closed. */
+
+        if (!sig_data)
+                return -ENOMEM;
+
         *ret_sig_data = TAKE_PTR(sig_data);
         *ret_sig_size = sig_size;
         return 0;
index d3175b1b9de30c265ae23c520b344f8545e11a0b..44d1d1f1e6e4ddcaac83fa4d4593ca56e9c516fd 100644 (file)
@@ -1222,19 +1222,20 @@ int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical) {
                 return 0;
 
         r = dns_packet_append_rr(&packet, rr, 0, &start, &rds);
-        if (r < 0)
+        if (r < 0) {
+                dns_packet_unref(&packet);
                 return r;
+        }
 
         assert(start == 0);
         assert(packet._data);
 
         free(rr->wire_format);
-        rr->wire_format = packet._data;
+        rr->wire_format = TAKE_PTR(packet._data);
         rr->wire_format_size = packet.size;
         rr->wire_format_rdata_offset = rds;
         rr->wire_format_canonical = canonical;
 
-        packet._data = NULL;
         dns_packet_unref(&packet);
 
         return 0;
index 184d8e3f3d33982123a4c415edd65c0daf8d7c29..67786d39fdbca3633c561eecec7bb086faeafc3c 100644 (file)
@@ -519,6 +519,11 @@ static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si
         if (fflush_and_check(f) < 0)
                 return log_oom();
 
+        f = safe_fclose(f);
+
+        if (!buffer)
+                return -ENOMEM;
+
         log_dump(LOG_INFO, buffer);
         return 0;
 }
index ca0d77c1367ab6c0ab2fd9f9a8b2085c6800c504..b99883a088e23353c8e32e9be39ff6e222019c64 100644 (file)
@@ -628,6 +628,9 @@ static int method_dump_memory_state_by_fd(sd_bus_message *message, void *userdat
 
         dump_file = safe_fclose(dump_file);
 
+        if (!dump)
+                return -ENOMEM;
+
         fd = acquire_data_fd(dump, dump_size, 0);
         if (fd < 0)
                 return fd;
index 78902dfbda68a7aa175069abf0f56ed4bd59dc94..fa19e4c95a5e8dcb811fb0421763c644cc9831ec 100644 (file)
@@ -12,6 +12,7 @@
 #include "alloc-util.h"
 #include "calendarspec.h"
 #include "errno-util.h"
+#include "fd-util.h"
 #include "fileio.h"
 #include "macro.h"
 #include "parse-util.h"
@@ -336,9 +337,9 @@ static void format_chain(FILE *f, int space, const CalendarComponent *c, bool us
 }
 
 int calendar_spec_to_string(const CalendarSpec *c, char **p) {
-        char *buf = NULL;
+        _cleanup_free_ char *buf = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         size_t sz = 0;
-        FILE *f;
         int r;
 
         assert(c);
@@ -383,14 +384,15 @@ int calendar_spec_to_string(const CalendarSpec *c, char **p) {
         }
 
         r = fflush_and_check(f);
-        fclose(f);
-
-        if (r < 0) {
-                free(buf);
+        if (r < 0)
                 return r;
-        }
 
-        *p = buf;
+        f = safe_fclose(f);
+
+        if (!buf)
+                return -ENOMEM;
+
+        *p = TAKE_PTR(buf);
         return 0;
 }
 
index 98c47d912500c9783cfdd35a6327fe778a0ff630..5885215a1ca24876bebbee9b847a02b5927863b6 100644 (file)
@@ -621,8 +621,13 @@ static int parse_core(int fd, const char *executable, char **ret, JsonVariant **
                         return log_warning_errno(r, "Could not parse core file, flushing file buffer failed: %m");
 
                 c.f = safe_fclose(c.f);
+
+                if (!buf)
+                        return log_oom();
+
                 *ret = TAKE_PTR(buf);
         }
+
         if (ret_package_metadata)
                 *ret_package_metadata = TAKE_PTR(package_metadata);
 
@@ -735,8 +740,13 @@ static int parse_elf(int fd, const char *executable, char **ret, JsonVariant **r
                         return log_warning_errno(r, "Could not parse ELF file, flushing file buffer failed: %m");
 
                 c.f = safe_fclose(c.f);
+
+                if (!buf)
+                        return log_oom();
+
                 *ret = TAKE_PTR(buf);
         }
+
         if (ret_package_metadata)
                 *ret_package_metadata = TAKE_PTR(elf_metadata);
 
index 204e8b68b6d5903c9b066862e60b68990816e819..83b749d677a4a9d90c012a6f0b53a9957abe3882 100644 (file)
@@ -2537,6 +2537,9 @@ int table_format(Table *t, char **ret) {
 
         f = safe_fclose(f);
 
+        if (!buf)
+                return -ENOMEM;
+
         *ret = TAKE_PTR(buf);
 
         return 0;
index 73050b55c856e20885db3f71b30f3e77a49b46f3..5bf00f009fcba9a8a8a1a0ff61c611a0a73025d6 100644 (file)
@@ -1769,6 +1769,7 @@ static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const cha
 
 int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
         _cleanup_free_ char *s = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         size_t sz = 0;
         int r;
 
@@ -1781,26 +1782,26 @@ int json_variant_format(JsonVariant *v, JsonFormatFlags flags, char **ret) {
         if (flags & JSON_FORMAT_OFF)
                 return -ENOEXEC;
 
-        {
-                _cleanup_fclose_ FILE *f = NULL;
-
-                f = open_memstream_unlocked(&s, &sz);
-                if (!f)
-                        return -ENOMEM;
+        f = open_memstream_unlocked(&s, &sz);
+        if (!f)
+                return -ENOMEM;
 
-                r = json_variant_dump(v, flags, f, NULL);
-                if (r < 0)
-                        return r;
+        r = json_variant_dump(v, flags, f, NULL);
+        if (r < 0)
+                return r;
 
-                /* Add terminating 0, so that the output buffer is a valid string. */
-                fputc('\0', f);
+        /* Add terminating 0, so that the output buffer is a valid string. */
+        fputc('\0', f);
 
-                r = fflush_and_check(f);
-        }
+        r = fflush_and_check(f);
         if (r < 0)
                 return r;
 
-        assert(s);
+        f = safe_fclose(f);
+
+        if (!s)
+                return -ENOMEM;
+
         *ret = TAKE_PTR(s);
         assert(sz > 0);
         return (int) sz - 1;
index 31390fbd89d51581a88b6480450409380ae31933..e5a1f94f2a2945478c6c9f2918ea18fb19ccfaa3 100644 (file)
@@ -284,7 +284,7 @@ int specifier_architecture(char specifier, const void *data, const char *root, c
  * installation. */
 
 static int parse_os_release_specifier(const char *root, const char *id, char **ret) {
-        char *v = NULL;
+        _cleanup_free_ char *v = NULL;
         int r;
 
         assert(ret);
@@ -293,7 +293,7 @@ static int parse_os_release_specifier(const char *root, const char *id, char **r
         if (r >= 0)
                 /* parse_os_release() calls parse_env_file() which only sets the return value for
                  * entries found. Let's make sure we set the return value in all cases. */
-                *ret = v;
+                *ret = TAKE_PTR(v);
 
         /* Translate error for missing os-release file to EUNATCH. */
         return r == -ENOENT ? -EUNATCH : r;