From 7ff1bfdb68ada2c07eafb3683c88810bd86de47e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 15:37:53 +0000 Subject: [PATCH 01/18] dissect: add asserts to appease coverity CID#1645844 CID#1645845 Follow-up for 91578e529395a0299a1e5eaa6da08e73db6eeacd --- src/shared/dissect-image.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index d68ea0bc97..4a8d4a5c0e 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1703,6 +1703,10 @@ static int dissect_image( PartitionDesignator dv = partition_verity_hash_of(*dd); PartitionDesignator ds = partition_verity_sig_of(*dd); + /* Hint to help static analyzers */ + assert(dv >= 0); + assert(ds >= 0); + if (!m->partitions[*dd].found && (m->partitions[dv].found || m->partitions[ds].found)) return log_debug_errno( SYNTHETIC_ERRNO(EADDRNOTAVAIL), From 9bdc8c8138373810e2509d19d2de61cf059fdfc2 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 17:56:51 +0000 Subject: [PATCH 02/18] imdsd: voidify unchecked call CID#1646046 Follow-up for eb6e5b07f13cefddf1f49e1f7bda4af22f5aba17 --- src/imds/imdsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imds/imdsd.c b/src/imds/imdsd.c index 565f21cfaa..68a03b7232 100644 --- a/src/imds/imdsd.c +++ b/src/imds/imdsd.c @@ -275,7 +275,7 @@ static void context_reset_for_refresh(Context *c) { c->child_data = hashmap_free(c->child_data); c->data_size = 0; - sd_event_source_set_enabled(c->retry_source, SD_EVENT_OFF); + (void) sd_event_source_set_enabled(c->retry_source, SD_EVENT_OFF); } static void context_reset_full(Context *c) { From 85b20f5fa7291eaf7effe62d88a8c0d5b79eee7c Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 18:29:28 +0000 Subject: [PATCH 03/18] boot: add overflow check in GPT parser ALIGN_TO() can overflow and return SIZE_MAX CID#1644887 Follow-up for ccbd324a3a522362de0863e8d06cdd06a58d2fca --- src/boot/part-discovery.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/boot/part-discovery.c b/src/boot/part-discovery.c index dc1aed0514..25f60521ac 100644 --- a/src/boot/part-discovery.c +++ b/src/boot/part-discovery.c @@ -117,6 +117,8 @@ static EFI_STATUS try_gpt( /* Now load the GPT entry table */ size = ALIGN_TO((size_t) gpt->SizeOfPartitionEntry * (size_t) gpt->NumberOfPartitionEntries, 512); + if (size == SIZE_MAX) /* overflow check */ + return EFI_OUT_OF_RESOURCES; entries_pages = xmalloc_aligned_pages( AllocateMaxAddress, EfiLoaderData, From 1a0fe20bc2278713b5185feee4578aabbce24b71 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 18:35:09 +0000 Subject: [PATCH 04/18] pe-binary: fix error reporting This is a local calculation, errno is not set Follow-up for a43427013949c6593629f551cf46e9cf9c167100 --- src/shared/pe-binary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/pe-binary.c b/src/shared/pe-binary.c index f342801bea..98b758dc4e 100644 --- a/src/shared/pe-binary.c +++ b/src/shared/pe-binary.c @@ -421,7 +421,7 @@ int pe_hash(int fd, if ((uint64_t) st.st_size > p) { if ((uint64_t) st.st_size - p < le32toh(certificate_table->Size)) - return log_debug_errno(errno, "No space for certificate table, refusing."); + return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "No space for certificate table, refusing."); r = hash_file(fd, mdctx, p, st.st_size - p - le32toh(certificate_table->Size)); if (r < 0) From 74a9ed911d878cffbdf9cb1d3c88088fae41aaaa Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 18:45:52 +0000 Subject: [PATCH 05/18] pe-binary: add explicit cast to silence coverity Otherwise it gets confused about underflows (which are already checked) CID#1645068 Follow-up for a43427013949c6593629f551cf46e9cf9c167100 --- src/shared/pe-binary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/pe-binary.c b/src/shared/pe-binary.c index 98b758dc4e..da54428306 100644 --- a/src/shared/pe-binary.c +++ b/src/shared/pe-binary.c @@ -423,7 +423,7 @@ int pe_hash(int fd, if ((uint64_t) st.st_size - p < le32toh(certificate_table->Size)) return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "No space for certificate table, refusing."); - r = hash_file(fd, mdctx, p, st.st_size - p - le32toh(certificate_table->Size)); + r = hash_file(fd, mdctx, p, (uint64_t) st.st_size - p - le32toh(certificate_table->Size)); if (r < 0) return r; From 8fe512a02ea05e16abb575945e53b84e284b6bc5 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 18:50:49 +0000 Subject: [PATCH 06/18] stat-util: fix return type of mode_verify_socket() It returns an error code, not a mode Follow-up for 97fe03e12faa4e50d25a3ca8999967801c7e2da9 --- src/basic/stat-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c index ac218d1552..9adb43df51 100644 --- a/src/basic/stat-util.c +++ b/src/basic/stat-util.c @@ -153,7 +153,7 @@ int is_symlink(const char *path) { return verify_stat_at(AT_FDCWD, path, false, stat_verify_symlink, false); } -static mode_t mode_verify_socket(mode_t mode) { +static int mode_verify_socket(mode_t mode) { if (S_ISLNK(mode)) return -ELOOP; From bf37ed0a659489c889ba9185f9f46c12c1ba7007 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 18:55:37 +0000 Subject: [PATCH 07/18] stat-util: add assert to silence coverity Coverity thinks _mntidb can be used uninitialized, but this is not the case when r == 0. Add a bool variable to make it clearer instead of reusing 'r' later, and an assert to guide static analyzers. CID#1644850 Follow-up for 5817c73391b5f3599c50df2c0873b26ea426f848 --- src/basic/stat-util.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c index 9adb43df51..d04da52a78 100644 --- a/src/basic/stat-util.c +++ b/src/basic/stat-util.c @@ -516,15 +516,17 @@ int inode_same_at(int fda, const char *filea, int fdb, const char *fileb, int fl goto fallback; } - if (r == 0) + bool have_unique_mntid = r > 0; + + if (!have_unique_mntid) mntida = _mntida; r = name_to_handle_at_try_fid( fdb, fileb, &hb, - r > 0 ? NULL : &_mntidb, /* if we managed to get unique mnt id for a, insist on that for b */ - r > 0 ? &mntidb : NULL, + have_unique_mntid ? NULL : &_mntidb, /* if we managed to get unique mnt id for a, insist on that for b */ + have_unique_mntid ? &mntidb : NULL, ntha_flags); if (r < 0) { if (is_name_to_handle_at_fatal_error(r)) @@ -532,8 +534,10 @@ int inode_same_at(int fda, const char *filea, int fdb, const char *fileb, int fl goto fallback; } - if (r == 0) + if (r == 0) { + assert(!have_unique_mntid); /* _mntidb was initialized by name_to_handle_at_try_fid() */ mntidb = _mntidb; + } /* Now compare the two file handles */ if (!file_handle_equal(ha, hb)) From 3e889473c9c0c16fe13c7e869203df1c274a0a2e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 19:05:19 +0000 Subject: [PATCH 08/18] resolved: fix TOCTOU in hook discovery Coverity complains that the directory is not pinned by FD so it might changed between the stat and the open CID#1643236 Follow-up for 8209f4adcde08d225f56269e608ccd5f6704cd70 --- src/resolve/resolved-hook.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/resolve/resolved-hook.c b/src/resolve/resolved-hook.c index 4938e2d2a1..9625e64fe2 100644 --- a/src/resolve/resolved-hook.c +++ b/src/resolve/resolved-hook.c @@ -391,19 +391,6 @@ static int manager_hook_discover(Manager *m) { usec_t seen_usec = now(CLOCK_MONOTONIC); - struct stat st; - if (stat(dp, &st) < 0) { - if (errno == ENOENT) - r = 0; - else - r = log_warning_errno(errno, "Failed to stat %s/: %m", dp); - - goto finish; - } - - if (stat_inode_unmodified(&st, &m->hook_stat)) - return 0; - d = opendir(dp); if (!d) { if (errno == ENOENT) @@ -414,6 +401,15 @@ static int manager_hook_discover(Manager *m) { goto finish; } + struct stat st; + if (fstat(dirfd(d), &st) < 0) { + r = log_warning_errno(errno, "Failed to fstat %s/: %m", dp); + goto finish; + } + + if (stat_inode_unmodified(&st, &m->hook_stat)) + return 0; + for (;;) { errno = 0; struct dirent *de = readdir_no_dot(d); From 86fd0337c652b04755008cdca23e2d9c727fa9a9 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 19:35:36 +0000 Subject: [PATCH 09/18] scsi_id: use strscpy instead of strncpy for wwn fields strncpy does not null-terminate the destination buffer if the source string is longer than the count parameter. Since wwn and wwn_vendor_extension are char[17] and we copy up to 16 bytes, there's a risk of missing null termination. Use strscpy which always null-terminates. CID#1469706 Follow-up for 4e9fdfccbdd16f0cfdb5c8fa8484a8ba0f2e69d3 --- src/udev/scsi_id/scsi_serial.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c index 20caf695bf..82557e3b05 100644 --- a/src/udev/scsi_id/scsi_serial.c +++ b/src/udev/scsi_id/scsi_serial.c @@ -21,6 +21,7 @@ #include "scsi.h" #include "scsi_id.h" #include "string-util.h" +#include "strxcpyx.h" #include "time-util.h" /* @@ -517,9 +518,9 @@ static int check_fill_0x83_id(struct scsi_id_device *dev_scsi, strcpy(serial_short, serial + s); if (id_search->id_type == SCSI_ID_NAA && wwn != NULL) { - strncpy(wwn, serial + s, 16); + strscpy(wwn, 17, serial + s); if (wwn_vendor_extension) - strncpy(wwn_vendor_extension, serial + s + 16, 16); + strscpy(wwn_vendor_extension, 17, serial + s + 16); } return 0; From 1929226e7e649b72f3f9acd464eaac771c00945c Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 19:47:27 +0000 Subject: [PATCH 10/18] debug-generator: use unsigned bit shift for breakpoint flags Using signed int literal '1' in left shift can lead to undefined behavior if the shift amount causes overflow of a signed int. Use UINT32_C(1) since the result is stored in a uint32_t variable. CID#1568482 Follow-up for e9f781a5a4721d3e58798b37e30bb4dcdbe54c02 --- src/debug-generator/debug-generator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c index 878e115232..e3b7768fbc 100644 --- a/src/debug-generator/debug-generator.c +++ b/src/debug-generator/debug-generator.c @@ -101,7 +101,7 @@ static int parse_breakpoint_from_string(const char *s, uint32_t *ret_breakpoints FOREACH_ELEMENT(i, breakpoint_info_table) if (FLAGS_SET(i->validity, BREAKPOINT_DEFAULT) && breakpoint_applies(i, INT_MAX)) { - breakpoints |= 1 << i->type; + breakpoints |= UINT32_C(1) << i->type; found_default = true; break; } @@ -127,7 +127,7 @@ static int parse_breakpoint_from_string(const char *s, uint32_t *ret_breakpoints } if (breakpoint_applies(&breakpoint_info_table[tt], LOG_WARNING)) - breakpoints |= 1 << tt; + breakpoints |= UINT32_C(1) << tt; } *ret_breakpoints = breakpoints; From be85048e280bd99ffe0e4ed8ea8695a2faf4f1ed Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 19:49:20 +0000 Subject: [PATCH 11/18] cpu-set-util: add asserts to guide static analysis after realloc Coverity flags CPU_SET_S() calls as potential out-of-bounds writes because it cannot trace that cpu_set_realloc() guarantees the allocated buffer is large enough for the given index. Add asserts to make the size invariant explicit. CID#1611787 CID#1611788 Follow-up for 0985c7c4e22c8dbbea4398cf3453da45ebf63800 --- src/shared/cpu-set-util.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/shared/cpu-set-util.c b/src/shared/cpu-set-util.c index e4ef36da9a..9211dbe47e 100644 --- a/src/shared/cpu-set-util.c +++ b/src/shared/cpu-set-util.c @@ -159,6 +159,8 @@ int cpu_set_add(CPUSet *c, size_t i) { if (r < 0) return r; + /* Silence static analyzers */ + assert(i / CHAR_BIT < c->allocated); CPU_SET_S(i, c->allocated, c->set); return 0; } @@ -194,6 +196,8 @@ int cpu_set_add_range(CPUSet *c, size_t start, size_t end) { if (r < 0) return r; + /* Silence static analyzers */ + assert(end / CHAR_BIT < c->allocated); for (size_t i = start; i <= end; i++) CPU_SET_S(i, c->allocated, c->set); From c8b53fcfd3463679e6475e9b57b61a97dac1a287 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 19:52:09 +0000 Subject: [PATCH 12/18] sd-event: add assert to help static analysis trace signal bounds Coverity flags the signal_sources array access as a potential out-of-bounds read because it cannot trace through the SIGNAL_VALID() macro to know that ssi_signo < _NSIG. Add an explicit assert after the runtime check to make the constraint visible to static analyzers. CID#1548033 Follow-up for 7a64c5f23efbb51fe4f1229c1a8aed6dd858a0a9 --- src/libsystemd/sd-event/sd-event.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index b78cfe86fa..6867385e92 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -3807,6 +3807,9 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events, i if (_unlikely_(!SIGNAL_VALID(si.ssi_signo))) return -EIO; + /* Silence static analyzers */ + assert(si.ssi_signo < _NSIG); + if (e->signal_sources) s = e->signal_sources[si.ssi_signo]; if (!s) From 1b7d2fa978d76a1caed7dc9e615e403a29ff6971 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 19:55:35 +0000 Subject: [PATCH 13/18] uid-range: add asserts to document overflow safety in coalesce Coverity flags the x->start + x->nr and y->start + y->nr additions as potential overflows. These are safe because uid_range_add_internal() validates start + nr <= UINT32_MAX before inserting entries. Add asserts to document this invariant for static analyzers. CID#1548015 Follow-up for 8530dc4467691a893aa2e07319b18a84fec96cad --- src/basic/uid-range.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/basic/uid-range.c b/src/basic/uid-range.c index 31305952ba..628710a870 100644 --- a/src/basic/uid-range.c +++ b/src/basic/uid-range.c @@ -63,6 +63,10 @@ static void uid_range_coalesce(UIDRange *range) { break; begin = MIN(x->start, y->start); + + /* Silence static analyzers, overflow is prevented by uid_range_add_internal() */ + assert(x->start <= UINT32_MAX - x->nr); + assert(y->start <= UINT32_MAX - y->nr); end = MAX(x->start + x->nr, y->start + y->nr); x->start = begin; From c34169e9d3048b7be6a7717860999029b58392df Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 20:08:55 +0000 Subject: [PATCH 14/18] sd-bus: add asserts for rbuffer_size accumulation bounds Coverity flags rbuffer_size += k as a potential overflow, but k is always bounded by the iov size (which is the difference between the allocated buffer and current rbuffer_size). Add asserts to make this invariant explicit. CID#1548044 CID#1548071 Follow-up for a7e3212d89d5aefee67de79c1e7eaccf2f5645ac --- src/libsystemd/sd-bus/bus-socket.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index 4cac317dff..3c6a2b2747 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -676,6 +676,8 @@ static int bus_socket_read_auth(sd_bus *b) { return -ECONNRESET; } + /* Silence static analyzers, k is bounded by iov size: n - rbuffer_size */ + assert((size_t) k <= n - b->rbuffer_size); b->rbuffer_size += k; if (handle_cmsg) { @@ -1453,6 +1455,8 @@ int bus_socket_read_message(sd_bus *bus) { return -EXFULL; } + /* Silence static analyzers, k is bounded by iov size: need - rbuffer_size */ + assert((size_t) k <= need - bus->rbuffer_size); bus->rbuffer_size += k; if (handle_cmsg) { From 2bd6930efeace1ef0bae4683ef38e9ad6f74dcd0 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 20:10:14 +0000 Subject: [PATCH 15/18] importd: add assert for log_message_size accumulation bounds Coverity flags log_message_size += l as a potential overflow, but l is bounded by the read() count parameter which is sizeof(log_message) - log_message_size. Add an assert to make this invariant explicit. CID#1548062 Follow-up for 3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3 --- src/import/importd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/import/importd.c b/src/import/importd.c index d3363d446c..fed2af4170 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -418,6 +418,8 @@ static int transfer_on_log(sd_event_source *s, int fd, uint32_t revents, void *u return 0; } + /* Silence static analyzers, l is bounded by read() count: sizeof - log_message_size */ + assert((size_t) l <= sizeof(t->log_message) - t->log_message_size); t->log_message_size += l; transfer_send_logs(t, false); From cda2962daf6fb9938237001ad8416ea3c7fff06b Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 20:13:03 +0000 Subject: [PATCH 16/18] compress: add assert for space doubling overflow safety Coverity flags 2 * space as a potential overflow. The space value is bounded by prior allocation success, but add an explicit assert to document this for static analyzers. CID#1548056 Follow-up for 5e592c66bdf76dfc8445b332f7a5088ca504ee90 --- src/basic/compress.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/basic/compress.c b/src/basic/compress.c index 5c9ca829df..d9759ad417 100644 --- a/src/basic/compress.c +++ b/src/basic/compress.c @@ -398,6 +398,8 @@ int decompress_blob_xz( return -ENOBUFS; used = space - s.avail_out; + /* Silence static analyzers, space is bounded by allocation size */ + assert(space <= SIZE_MAX / 2); space = MIN(2 * space, dst_max ?: SIZE_MAX); if (!greedy_realloc(dst, space, 1)) return -ENOMEM; From 3e38052f1ddda29ee0d7b8a235fd9bebc39774c0 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 20:13:40 +0000 Subject: [PATCH 17/18] exec-util: use unsigned shift for ExecCommandFlags Using signed int literal '1' in left shift operations can theoretically lead to undefined behavior. Use 1U to be explicit about unsigned arithmetic. CID#1548018 Follow-up for b3d593673c5b8b0b7d781fd26ab2062ca6e7dbdb --- src/shared/exec-util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/exec-util.c b/src/shared/exec-util.c index 2e15f311b8..420803c77d 100644 --- a/src/shared/exec-util.c +++ b/src/shared/exec-util.c @@ -500,7 +500,7 @@ assert_cc((1 << ELEMENTSOF(exec_command_strings)) - 1 == _EXEC_COMMAND_FLAGS_ALL const char* exec_command_flags_to_string(ExecCommandFlags i) { for (size_t idx = 0; idx < ELEMENTSOF(exec_command_strings); idx++) - if (i == (1 << idx)) + if (i == (ExecCommandFlags) (1U << idx)) return exec_command_strings[idx]; return NULL; @@ -516,7 +516,7 @@ ExecCommandFlags exec_command_flags_from_string(const char *s) { if (idx < 0) return _EXEC_COMMAND_FLAGS_INVALID; - return 1 << idx; + return 1U << idx; } int fexecve_or_execve(int executable_fd, const char *executable, char *const argv[], char *const envp[]) { From 4b25c74c20b064143dd3367ddb26fefff1e2ebbf Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Mar 2026 20:24:22 +0000 Subject: [PATCH 18/18] recurse-dir: add assert_cc for DIRENT_SIZE_MAX allocation Coverity flags offsetof(DirectoryEntries, buffer) + DIRENT_SIZE_MAX * 8 as a potential overflow. All operands are compile-time constants, so add an assert_cc() to prove this at build time. CID#1548020 Follow-up for 6393b847f459dba14d2b615ee93babb143168b57 --- src/basic/recurse-dir.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/basic/recurse-dir.c b/src/basic/recurse-dir.c index 0efa731868..bc3c32afe6 100644 --- a/src/basic/recurse-dir.c +++ b/src/basic/recurse-dir.c @@ -41,6 +41,8 @@ int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret) { * Start with space for up to 8 directory entries. We expect at least 2 ("." + ".."), hence hopefully * 8 will cover most cases comprehensively. (Note that most likely a lot more entries will actually * fit in the buffer, given we calculate maximum file name length here.) */ + /* Silence static analyzers */ + assert_cc(offsetof(DirectoryEntries, buffer) <= SIZE_MAX - DIRENT_SIZE_MAX * 8); de = malloc(offsetof(DirectoryEntries, buffer) + DIRENT_SIZE_MAX * 8); if (!de) return -ENOMEM;