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, ¤t) != 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 */