@cryptotaxi247 / netdata-1 / commits / ae7cf1b9a

Fix based on Coverity and Sonar audits (part 9) (#22337)

Harden vendored netipc Coverity paths Co-authored-by: Costa Tsaousis <costa@netdata.cloud>

Stelios Fragkakis committed May 3, 2026 at 11:59 UTC ae7cf1b9a7ae9cfc27905c34f18f0fab4faf14dd
7 files changed +224 -52
src/libnetdata/netipc/src/protocol/netipc_protocol.c
+4 -2
@@ -751,9 +751,11 @@ nipc_error_t nipc_increment_decode(const void *buf, size_t buf_len,
751
752 size_t nipc_string_reverse_encode(const char *str, uint32_t str_len,
753 void *buf, size_t buf_len) {
754 - /* Guard against size_t overflow on 32-bit platforms */
755 - if (str_len > SIZE_MAX - NIPC_STRING_REVERSE_HDR_SIZE - 1)
754 + /* Guard against size_t overflow only where uint32_t can exceed size_t. */
755 +#if SIZE_MAX <= UINT32_MAX
756 + if ((size_t)str_len > SIZE_MAX - (size_t)NIPC_STRING_REVERSE_HDR_SIZE - 1u)
757 return 0;
758 +#endif
759
760 size_t total = NIPC_STRING_REVERSE_HDR_SIZE + str_len + 1;
761 if (buf_len < total)
src/libnetdata/netipc/src/service/netipc_service.c
+55 -9
@@ -16,6 +16,7 @@
16
17 #include <errno.h>
18 #include <poll.h>
19 +#include <stdint.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/socket.h>
@@ -152,6 +153,26 @@ static bool ensure_buffer(uint8_t **buf, size_t *buf_size, size_t need, int faul
153 return true;
154 }
155
156 +static bool header_payload_len(size_t payload_len, size_t *msg_len_out)
157 +{
158 +#if SIZE_MAX <= UINT32_MAX
159 + if (payload_len > SIZE_MAX - NIPC_HEADER_LEN)
160 + return false;
161 +#endif
162 +
163 + *msg_len_out = NIPC_HEADER_LEN + payload_len;
164 + return true;
165 +}
166 +
167 +static bool header_payload_len_u32(uint32_t payload_len, uint32_t *msg_len_out)
168 +{
169 + if (payload_len > UINT32_MAX - NIPC_HEADER_LEN)
170 + return false;
171 +
172 + *msg_len_out = payload_len + NIPC_HEADER_LEN;
173 + return true;
174 +}
175 +
176 static void client_note_request_capacity(nipc_client_ctx_t *ctx, uint32_t payload_len)
177 {
178 uint32_t grown = next_power_of_2_u32(payload_len);
@@ -172,7 +193,9 @@ static void client_note_response_capacity(nipc_client_ctx_t *ctx, uint32_t paylo
193
194 static bool client_prepare_session_buffers(nipc_client_ctx_t *ctx)
195 {
175 - size_t response_need = (size_t)ctx->session.max_response_payload_bytes + NIPC_HEADER_LEN;
196 + size_t response_need;
197 + if (!header_payload_len(ctx->session.max_response_payload_bytes, &response_need))
198 + return false;
199 if (response_need < NIPC_HEADER_LEN + 1024u)
200 response_need = NIPC_HEADER_LEN + 1024u;
201
@@ -182,7 +205,9 @@ static bool client_prepare_session_buffers(nipc_client_ctx_t *ctx)
205
206 if (ctx->session.selected_profile == NIPC_PROFILE_SHM_HYBRID ||
207 ctx->session.selected_profile == NIPC_PROFILE_SHM_FUTEX) {
185 - size_t send_need = (size_t)ctx->session.max_request_payload_bytes + NIPC_HEADER_LEN;
208 + size_t send_need;
209 + if (!header_payload_len(ctx->session.max_request_payload_bytes, &send_need))
210 + return false;
211 if (!ensure_buffer(&ctx->send_buf, &ctx->send_buf_size, send_need,
212 NIPC_POSIX_SERVICE_TEST_FAULT_CLIENT_SEND_BUF_REALLOC_INTERNAL))
213 return false;
@@ -373,7 +398,10 @@ static nipc_error_t transport_send(nipc_client_ctx_t *ctx,
398 return NIPC_ERR_OVERFLOW;
399 }
400
376 - size_t msg_len = NIPC_HEADER_LEN + payload_len;
401 + size_t msg_len;
402 + if (!header_payload_len(payload_len, &msg_len))
403 + return NIPC_ERR_OVERFLOW;
404 +
405 uint8_t *msg = ctx->send_buf;
406 if (!msg || msg_len > ctx->send_buf_size)
407 return NIPC_ERR_OVERFLOW;
@@ -830,7 +858,9 @@ static void server_handle_session(nipc_managed_server_t *server,
858 size_t resp_buf_size)
859 {
860 /* Allocate recv buffer based on negotiated max request size */
833 - size_t recv_size = NIPC_HEADER_LEN + session->max_request_payload_bytes;
861 + size_t recv_size;
862 + if (!header_payload_len(session->max_request_payload_bytes, &recv_size))
863 + return;
864 if (recv_size < NIPC_HEADER_LEN + 1024u)
865 recv_size = NIPC_HEADER_LEN + 1024u;
866 uint8_t *recv_buf = service_malloc(
@@ -948,7 +978,9 @@ static void server_handle_session(nipc_managed_server_t *server,
978
979 switch (dispatch_err) {
980 case NIPC_OK:
951 - if (response_len > session->max_response_payload_bytes) {
981 + if (response_len > resp_buf_size ||
982 + response_len > session->max_response_payload_bytes ||
983 + response_len > SIZE_MAX - NIPC_HEADER_LEN) {
984 server_note_response_capacity(
985 server,
986 response_len >= UINT32_MAX ? UINT32_MAX : (uint32_t)response_len);
@@ -987,7 +1019,9 @@ static void server_handle_session(nipc_managed_server_t *server,
1019
1020 /* Send response via the active transport */
1021 if (shm) {
990 - size_t msg_len = NIPC_HEADER_LEN + response_len;
1022 + size_t msg_len;
1023 + if (!header_payload_len(response_len, &msg_len))
1024 + break;
1025
1026 resp_hdr.magic = NIPC_MAGIC_MSG;
1027 resp_hdr.version = NIPC_VERSION;
@@ -1109,6 +1143,15 @@ static bool server_prepare_accept_config(nipc_managed_server_t *server,
1143 if (shm_profiles == 0)
1144 return true;
1145
1146 + uint32_t request_capacity;
1147 + uint32_t response_capacity;
1148 + if (!header_payload_len_u32(NIPC_MAX_PAYLOAD_CAP, &request_capacity) ||
1149 + !header_payload_len_u32(cfg_out->max_response_payload_bytes, &response_capacity)) {
1150 + cfg_out->supported_profiles &= ~shm_profiles;
1151 + cfg_out->preferred_profiles &= ~shm_profiles;
1152 + return cfg_out->supported_profiles != 0;
1153 + }
1154 +
1155 nipc_shm_ctx_t *shm = service_calloc(
1156 1, sizeof(nipc_shm_ctx_t),
1157 NIPC_POSIX_SERVICE_TEST_FAULT_SERVER_SHM_CTX_CALLOC_INTERNAL);
@@ -1120,8 +1163,8 @@ static bool server_prepare_accept_config(nipc_managed_server_t *server,
1163 nipc_shm_error_t serr = nipc_shm_server_create(
1164 server->run_dir, server->service_name,
1165 sid,
1123 - NIPC_MAX_PAYLOAD_CAP + NIPC_HEADER_LEN,
1124 - cfg_out->max_response_payload_bytes + NIPC_HEADER_LEN,
1166 + request_capacity,
1167 + response_capacity,
1168 shm);
1169 if (serr == NIPC_SHM_OK) {
1170 *shm_out = shm;
@@ -1147,12 +1190,15 @@ static nipc_error_t server_init_raw(nipc_managed_server_t *server,
1190 nipc_server_handler_fn handler,
1191 void *user)
1192 {
1193 + if (!server)
1194 + return NIPC_ERR_BAD_LAYOUT;
1195 +
1196 memset(server, 0, sizeof(*server));
1197 server->listener.fd = -1;
1198 __atomic_store_n(&server->running, false, __ATOMIC_RELAXED);
1199 server->acceptor_started = false;
1200
1155 - if (!run_dir || !service_name || !handler)
1201 + if (!run_dir || !service_name || !config || !handler)
1202 return NIPC_ERR_BAD_LAYOUT;
1203
1204 if (worker_count < 1)
src/libnetdata/netipc/src/service/netipc_service_win.c
+55 -9
@@ -16,6 +16,7 @@
16 #include "netipc/netipc_named_pipe.h"
17 #include "netipc/netipc_win_shm.h"
18
19 +#include <stdint.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <process.h>
@@ -162,6 +163,26 @@ static bool ensure_buffer(uint8_t **buf, size_t *buf_size, size_t need, int faul
163 return true;
164 }
165
166 +static bool header_payload_len(size_t payload_len, size_t *msg_len_out)
167 +{
168 +#if SIZE_MAX <= UINT32_MAX
169 + if (payload_len > SIZE_MAX - NIPC_HEADER_LEN)
170 + return false;
171 +#endif
172 +
173 + *msg_len_out = NIPC_HEADER_LEN + payload_len;
174 + return true;
175 +}
176 +
177 +static bool header_payload_len_u32(uint32_t payload_len, uint32_t *msg_len_out)
178 +{
179 + if (payload_len > UINT32_MAX - NIPC_HEADER_LEN)
180 + return false;
181 +
182 + *msg_len_out = payload_len + NIPC_HEADER_LEN;
183 + return true;
184 +}
185 +
186 static void client_note_request_capacity(nipc_client_ctx_t *ctx, uint32_t payload_len)
187 {
188 uint32_t grown = next_power_of_2_u32(payload_len);
@@ -182,7 +203,9 @@ static void client_note_response_capacity(nipc_client_ctx_t *ctx, uint32_t paylo
203
204 static bool client_prepare_session_buffers(nipc_client_ctx_t *ctx)
205 {
185 - size_t response_need = (size_t)ctx->session.max_response_payload_bytes + NIPC_HEADER_LEN;
206 + size_t response_need;
207 + if (!header_payload_len(ctx->session.max_response_payload_bytes, &response_need))
208 + return false;
209 if (response_need < NIPC_HEADER_LEN + 1024u)
210 response_need = NIPC_HEADER_LEN + 1024u;
211
@@ -192,7 +215,9 @@ static bool client_prepare_session_buffers(nipc_client_ctx_t *ctx)
215
216 if (ctx->session.selected_profile == NIPC_WIN_SHM_PROFILE_HYBRID ||
217 ctx->session.selected_profile == NIPC_WIN_SHM_PROFILE_BUSYWAIT) {
195 - size_t send_need = (size_t)ctx->session.max_request_payload_bytes + NIPC_HEADER_LEN;
218 + size_t send_need;
219 + if (!header_payload_len(ctx->session.max_request_payload_bytes, &send_need))
220 + return false;
221 if (!ensure_buffer(&ctx->send_buf, &ctx->send_buf_size, send_need,
222 NIPC_WIN_SERVICE_TEST_FAULT_CLIENT_SEND_BUF_REALLOC_INTERNAL))
223 return false;
@@ -387,7 +412,10 @@ static nipc_error_t transport_send(nipc_client_ctx_t *ctx,
412 return NIPC_ERR_OVERFLOW;
413 }
414
390 - size_t msg_len = NIPC_HEADER_LEN + payload_len;
415 + size_t msg_len;
416 + if (!header_payload_len(payload_len, &msg_len))
417 + return NIPC_ERR_OVERFLOW;
418 +
419 uint8_t *msg = ctx->send_buf;
420 if (!msg || msg_len > ctx->send_buf_size)
421 return NIPC_ERR_OVERFLOW;
@@ -747,7 +775,9 @@ static void server_handle_session(nipc_managed_server_t *server,
775 size_t resp_buf_size)
776 {
777 /* Dynamically allocate recv buffer based on negotiated max */
750 - size_t recv_size = NIPC_HEADER_LEN + session->max_request_payload_bytes;
778 + size_t recv_size;
779 + if (!header_payload_len(session->max_request_payload_bytes, &recv_size))
780 + return;
781 if (recv_size < NIPC_HEADER_LEN + 1024u)
782 recv_size = NIPC_HEADER_LEN + 1024u;
783 uint8_t *recv_buf = service_malloc(
@@ -874,7 +904,9 @@ static void server_handle_session(nipc_managed_server_t *server,
904
905 switch (dispatch_err) {
906 case NIPC_OK:
877 - if (response_len > session->max_response_payload_bytes) {
907 + if (response_len > resp_buf_size ||
908 + response_len > session->max_response_payload_bytes ||
909 + response_len > SIZE_MAX - NIPC_HEADER_LEN) {
910 server_note_response_capacity(
911 server,
912 response_len >= UINT32_MAX ? UINT32_MAX : (uint32_t)response_len);
@@ -913,7 +945,9 @@ static void server_handle_session(nipc_managed_server_t *server,
945
946 /* Send response via the active transport */
947 if (shm) {
916 - size_t msg_len = NIPC_HEADER_LEN + response_len;
948 + size_t msg_len;
949 + if (!header_payload_len(response_len, &msg_len))
950 + break;
951
952 resp_hdr.magic = NIPC_MAGIC_MSG;
953 resp_hdr.version = NIPC_VERSION;
@@ -1120,6 +1154,15 @@ static bool server_prepare_accept_config(nipc_managed_server_t *server,
1154 if (shm_profiles == 0)
1155 return true;
1156
1157 + uint32_t request_capacity;
1158 + uint32_t response_capacity;
1159 + if (!header_payload_len_u32(NIPC_MAX_PAYLOAD_CAP, &request_capacity) ||
1160 + !header_payload_len_u32(cfg_out->max_response_payload_bytes, &response_capacity)) {
1161 + cfg_out->supported_profiles &= ~shm_profiles;
1162 + cfg_out->preferred_profiles &= ~shm_profiles;
1163 + return cfg_out->supported_profiles != 0;
1164 + }
1165 +
1166 const uint32_t profiles[] = {
1167 NIPC_WIN_SHM_PROFILE_HYBRID,
1168 NIPC_WIN_SHM_PROFILE_BUSYWAIT,
@@ -1142,8 +1185,8 @@ static bool server_prepare_accept_config(nipc_managed_server_t *server,
1185 server->auth_token,
1186 sid,
1187 profile,
1145 - NIPC_MAX_PAYLOAD_CAP + NIPC_HEADER_LEN,
1146 - cfg_out->max_response_payload_bytes + NIPC_HEADER_LEN,
1188 + request_capacity,
1189 + response_capacity,
1190 ctx);
1191 if (serr == NIPC_WIN_SHM_OK) {
1192 if (profile == NIPC_WIN_SHM_PROFILE_HYBRID)
@@ -1210,11 +1253,14 @@ static nipc_error_t server_init_raw(nipc_managed_server_t *server,
1253 nipc_server_handler_fn handler,
1254 void *user)
1255 {
1256 + if (!server)
1257 + return NIPC_ERR_BAD_LAYOUT;
1258 +
1259 memset(server, 0, sizeof(*server));
1260 server->listener.pipe = INVALID_HANDLE_VALUE;
1261 InterlockedExchange(&server->running, 0);
1262
1217 - if (!run_dir || !service_name || !handler)
1263 + if (!run_dir || !service_name || !config || !handler)
1264 return NIPC_ERR_BAD_LAYOUT;
1265
1266 if (worker_count < 1)
src/libnetdata/netipc/src/transport/posix/netipc_shm.c
+46 -19
@@ -22,6 +22,7 @@
22 #include <sys/mman.h>
23 #include <sys/stat.h>
24 #include <sys/syscall.h>
25 +#include <sys/types.h>
26
27 #include <linux/futex.h>
28
@@ -147,32 +148,57 @@ static inline uint32_t *shm_u32_ptr(void *base, int offset)
148 * -1 = doesn't exist
149 * -2 = exists but undersized / invalid (treated as stale, unlinked)
150 */
150 -static int check_shm_stale(const char *path)
151 +static int unlink_same_file(const char *path, const struct stat *expected)
152 {
152 - struct stat st;
153 - if (stat(path, &st) != 0)
153 + struct stat current;
154 + if (lstat(path, &current) != 0)
155 + return (errno == ENOENT) ? 0 : -1;
156 +
157 + if (current.st_dev != expected->st_dev || current.st_ino != expected->st_ino)
158 return -1;
159
156 - /* Must be at least header-sized to inspect. */
157 - if ((size_t)st.st_size < NIPC_SHM_HEADER_LEN) {
158 - unlink(path);
159 - return -2;
160 - }
160 + if (unlink(path) == 0 || errno == ENOENT)
161 + return 0;
162
163 + return -1;
164 +}
165 +
166 +static int check_shm_stale(const char *path)
167 +{
168 +#ifdef O_NOFOLLOW
169 + int fd = open(path, O_RDONLY | O_NOFOLLOW);
170 +#else
171 int fd = open(path, O_RDONLY);
172 +#endif
173 if (fd < 0) {
164 - /* Don't unlink on permission errors — the file may be owned by
165 - * another user/process and we just can't read it. */
166 - if (errno != EACCES && errno != EPERM)
167 - unlink(path);
168 - return -2;
174 + if (errno == ENOENT)
175 + return -1;
176 + /* Symlinks, permission failures, and other ambiguous path states are
177 + * treated as live so stale recovery cannot remove an unsafe path. */
178 + return 1;
179 + }
180 +
181 + struct stat st;
182 + if (fstat(fd, &st) != 0) {
183 + close(fd);
184 + return 1;
185 + }
186 +
187 + if (!S_ISREG(st.st_mode)) {
188 + close(fd);
189 + return 1;
190 + }
191 +
192 + /* Must be at least header-sized to inspect. */
193 + if (st.st_size < (off_t)NIPC_SHM_HEADER_LEN) {
194 + close(fd);
195 + return (unlink_same_file(path, &st) == 0) ? -2 : 1;
196 }
197
198 void *map = mmap(NULL, NIPC_SHM_HEADER_LEN, PROT_READ, MAP_SHARED, fd, 0);
199 close(fd);
200 if (map == MAP_FAILED) {
174 - unlink(path);
175 - return -2;
201 + return (unlink_same_file(path, &st) == 0) ? -2 : 1;
202 }
203
204 const nipc_shm_region_header_t *hdr = (const nipc_shm_region_header_t *)map;
@@ -180,8 +206,7 @@ static int check_shm_stale(const char *path)
206 /* Validate magic first. */
207 if (hdr->magic != NIPC_SHM_REGION_MAGIC) {
208 munmap(map, NIPC_SHM_HEADER_LEN);
183 - unlink(path);
184 - return -2;
209 + return (unlink_same_file(path, &st) == 0) ? -2 : 1;
210 }
211
212 int32_t owner = hdr->owner_pid;
@@ -193,8 +218,7 @@ static int check_shm_stale(const char *path)
218 }
219
220 /* Dead owner or zero generation (uninitialized/legacy) — stale */
196 - unlink(path);
197 - return 0;
221 + return (unlink_same_file(path, &st) == 0) ? 0 : 1;
222 }
223
224 /* ------------------------------------------------------------------ */
@@ -232,6 +256,9 @@ nipc_shm_error_t nipc_shm_server_create(const char *run_dir,
256 if (req_capacity > UINT32_MAX - req_off)
257 return NIPC_SHM_ERR_BAD_PARAM;
258 uint32_t resp_off = align64(req_off + req_capacity);
259 + if (resp_capacity > UINT32_MAX - resp_off ||
260 + (size_t)resp_off > SIZE_MAX - (size_t)resp_capacity)
261 + return NIPC_SHM_ERR_BAD_PARAM;
262 size_t region_size = (size_t)resp_off + resp_capacity;
263
264 /* Try O_EXCL create first (fast path, no stale check needed). */
src/libnetdata/netipc/src/transport/posix/netipc_uds.c
+41 -11
@@ -31,6 +31,17 @@
31 /* Internal helpers */
32 /* ------------------------------------------------------------------ */
33
34 +static bool header_payload_len(size_t payload_len, size_t *msg_len_out)
35 +{
36 +#if SIZE_MAX <= UINT32_MAX
37 + if (payload_len > SIZE_MAX - NIPC_HEADER_LEN)
38 + return false;
39 +#endif
40 +
41 + *msg_len_out = NIPC_HEADER_LEN + payload_len;
42 + return true;
43 +}
44 +
45 /* Validate service_name: only [a-zA-Z0-9._-], non-empty, not "." or "..". */
46 static int validate_service_name(const char *name)
47 {
@@ -491,13 +502,24 @@ static nipc_uds_error_t server_handshake(int fd,
502 /* Stale endpoint recovery */
503 /* ------------------------------------------------------------------ */
504
494 -/* Returns: 0 = stale (unlinked), 1 = live server, -1 = doesn't exist */
495 -static int check_and_recover_stale(const char *path)
505 +static int unlink_stale_socket_path(const char *path)
506 {
507 struct stat st;
498 - if (stat(path, &st) != 0)
499 - return -1; /* doesn't exist */
508 + if (lstat(path, &st) != 0)
509 + return (errno == ENOENT) ? 0 : -1;
510 +
511 + if (!S_ISSOCK(st.st_mode))
512 + return -1;
513 +
514 + if (unlink(path) == 0 || errno == ENOENT)
515 + return 0;
516
517 + return -1;
518 +}
519 +
520 +/* Returns: 0 = stale (unlinked), 1 = live server, -1 = doesn't exist */
521 +static int check_and_recover_stale(const char *path)
522 +{
523 /* Try connecting to check if a live server is there */
524 int probe = socket(AF_UNIX, SOCK_SEQPACKET, 0);
525 if (probe < 0)
@@ -516,11 +538,12 @@ static int check_and_recover_stale(const char *path)
538 } else {
539 int saved_errno = errno;
540 close(probe);
519 - /* Only unlink on ECONNREFUSED/ENOENT (stale socket).
520 - * Other errors (EACCES, etc.) should not remove the file. */
521 - if (saved_errno == ECONNREFUSED || saved_errno == ENOENT) {
522 - unlink(path);
523 - ret = 0;
541 + /* Only ECONNREFUSED proves a stale socket path. Other errors
542 + * (including regular files at the path) must not remove anything. */
543 + if (saved_errno == ENOENT) {
544 + ret = -1;
545 + } else if (saved_errno == ECONNREFUSED) {
546 + ret = (unlink_stale_socket_path(path) == 0) ? 0 : 1;
547 } else {
548 /* Can't determine ownership — treat as live to prevent overwriting */
549 ret = 1;
@@ -792,7 +815,12 @@ nipc_uds_error_t nipc_uds_send(nipc_uds_session_t *session,
815 hdr->header_len = NIPC_HEADER_LEN;
816 hdr->payload_len = (uint32_t)payload_len;
817
795 - size_t total_msg = NIPC_HEADER_LEN + payload_len;
818 + size_t total_msg;
819 + if (!header_payload_len(payload_len, &total_msg)) {
820 + if (tracked)
821 + inflight_remove(session, hdr->message_id);
822 + return NIPC_UDS_ERR_LIMIT_EXCEEDED;
823 + }
824
825 /* Does it fit in one packet? */
826 if (total_msg <= session->packet_size) {
@@ -979,7 +1007,9 @@ nipc_uds_error_t nipc_uds_receive(nipc_uds_session_t *session,
1007 return NIPC_UDS_ERR_UNKNOWN_MSG_ID;
1008 }
1009
982 - size_t total_msg = NIPC_HEADER_LEN + hdr_out->payload_len;
1010 + size_t total_msg;
1011 + if (!header_payload_len(hdr_out->payload_len, &total_msg))
1012 + return NIPC_UDS_ERR_LIMIT_EXCEEDED;
1013
1014 /* Non-chunked: entire message arrived in one packet */
1015 if ((size_t)n >= total_msg) {
src/libnetdata/netipc/src/transport/windows/netipc_named_pipe.c
+20 -2
@@ -48,6 +48,17 @@ static inline uint32_t apply_default(uint32_t val, uint32_t def)
48 return val == 0 ? def : val;
49 }
50
51 +static bool header_payload_len(size_t payload_len, size_t *msg_len_out)
52 +{
53 +#if SIZE_MAX <= UINT32_MAX
54 + if (payload_len > SIZE_MAX - NIPC_HEADER_LEN)
55 + return false;
56 +#endif
57 +
58 + *msg_len_out = NIPC_HEADER_LEN + payload_len;
59 + return true;
60 +}
61 +
62 static inline uint32_t pipe_buffer_size(uint32_t packet_size)
63 {
64 /* The protocol packet size controls logical framing and chunk size. The
@@ -927,7 +938,12 @@ nipc_np_error_t nipc_np_send(nipc_np_session_t *session,
938 hdr->header_len = NIPC_HEADER_LEN;
939 hdr->payload_len = (uint32_t)payload_len;
940
930 - size_t total_msg = NIPC_HEADER_LEN + payload_len;
941 + size_t total_msg;
942 + if (!header_payload_len(payload_len, &total_msg)) {
943 + if (tracked)
944 + inflight_remove(session, hdr->message_id);
945 + return NIPC_NP_ERR_LIMIT_EXCEEDED;
946 + }
947
948 /* Single packet? */
949 if (total_msg <= session->packet_size) {
@@ -1106,7 +1122,9 @@ nipc_np_error_t nipc_np_receive(nipc_np_session_t *session,
1122 return NIPC_NP_ERR_UNKNOWN_MSG_ID;
1123 }
1124
1109 - size_t total_msg = NIPC_HEADER_LEN + hdr_out->payload_len;
1125 + size_t total_msg;
1126 + if (!header_payload_len(hdr_out->payload_len, &total_msg))
1127 + return NIPC_NP_ERR_LIMIT_EXCEEDED;
1128
1129 /* Non-chunked: entire message in one read */
1130 if (n >= total_msg) {
src/libnetdata/netipc/src/transport/windows/netipc_win_shm.c
+3
@@ -303,6 +303,9 @@ nipc_win_shm_error_t nipc_win_shm_server_create(
303 if (req_capacity > UINT32_MAX - req_off)
304 return NIPC_WIN_SHM_ERR_BAD_PARAM;
305 uint32_t resp_off = align_cacheline(req_off + req_capacity);
306 + if (resp_capacity > UINT32_MAX - resp_off ||
307 + (size_t)resp_off > SIZE_MAX - (size_t)resp_capacity)
308 + return NIPC_WIN_SHM_ERR_BAD_PARAM;
309 size_t region_size = (size_t)resp_off + resp_capacity;
310
311 /* Create file mapping backed by page file */