@cryptotaxi247 / netdata-1 / commits / 078015b98

Spawn server fixes No 4 (#18127)

add a magic number to all spawn server replies to ensure they are not corrupted

Costa Tsaousis committed Jul 12, 2024 at 13:54 UTC 078015b98234bfb59607144f91c86e7571a27c6e
1 file changed +48 -11
src/libnetdata/spawn_server/spawn_server.c
+48 -11
@@ -323,13 +323,17 @@ static int connect_to_spawn_server(const char *path, bool log) {
323 // the child created by the spawn server
324
325 typedef enum __attribute__((packed)) {
326 + STATUS_REPORT_NONE = 0,
327 STATUS_REPORT_STARTED,
328 STATUS_REPORT_FAILED,
329 STATUS_REPORT_EXITED,
330 STATUS_REPORT_PING,
331 } STATUS_REPORT;
332
333 +#define STATUS_REPORT_MAGIC 0xBADA55EE
334 +
335 struct status_report {
336 + uint32_t magic;
337 STATUS_REPORT status;
338 union {
339 struct {
@@ -346,17 +350,20 @@ struct status_report {
350 };
351 };
352
349 -static void spawn_server_send_status_ping(int fd) {
353 +static void spawn_server_send_status_ping(int sock) {
354 struct status_report sr = {
355 + .magic = STATUS_REPORT_MAGIC,
356 .status = STATUS_REPORT_PING,
357 };
358
354 - if(write(fd, &sr, sizeof(sr)) != sizeof(sr))
355 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "SPAWN SERVER: Cannot send ping status report");
359 + if(write(sock, &sr, sizeof(sr)) != sizeof(sr))
360 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
361 + "SPAWN SERVER: Cannot send ping reply.");
362 }
363
364 static void spawn_server_send_status_success(SPAWN_REQUEST *rq) {
365 const struct status_report sr = {
366 + .magic = STATUS_REPORT_MAGIC,
367 .status = STATUS_REPORT_STARTED,
368 .started = {
369 .pid = getpid(),
@@ -364,11 +371,14 @@ static void spawn_server_send_status_success(SPAWN_REQUEST *rq) {
371 };
372
373 if(write(rq->sock, &sr, sizeof(sr)) != sizeof(sr))
367 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "SPAWN SERVER: Cannot send success status report");
374 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
375 + "SPAWN SERVER: Cannot send success status report for request %zu: %s",
376 + rq->request_id, rq->cmdline);
377 }
378
379 static void spawn_server_send_status_failure(SPAWN_REQUEST *rq) {
380 struct status_report sr = {
381 + .magic = STATUS_REPORT_MAGIC,
382 .status = STATUS_REPORT_FAILED,
383 .failed = {
384 .err_no = errno,
@@ -376,11 +386,14 @@ static void spawn_server_send_status_failure(SPAWN_REQUEST *rq) {
386 };
387
388 if(write(rq->sock, &sr, sizeof(sr)) != sizeof(sr))
379 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "SPAWN SERVER: Cannot send failure status report");
389 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
390 + "SPAWN SERVER: Cannot send failure status report for request %zu: %s",
391 + rq->request_id, rq->cmdline);
392 }
393
394 static void spawn_server_send_status_exit(SPAWN_REQUEST *rq, int waitpid_status) {
395 struct status_report sr = {
396 + .magic = STATUS_REPORT_MAGIC,
397 .status = STATUS_REPORT_EXITED,
398 .exited = {
399 .waitpid_status = waitpid_status,
@@ -388,7 +401,9 @@ static void spawn_server_send_status_exit(SPAWN_REQUEST *rq, int waitpid_status)
401 };
402
403 if(write(rq->sock, &sr, sizeof(sr)) != sizeof(sr))
391 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "SPAWN SERVER: Cannot send exit status report");
404 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
405 + "SPAWN SERVER: Cannot send exit status (%d) report for request %zu: %s",
406 + waitpid_status, rq->request_id, rq->cmdline);
407 }
408
409 static void spawn_server_run_child(SPAWN_SERVER *server, SPAWN_REQUEST *rq) {
@@ -1357,8 +1372,15 @@ int spawn_server_exec_wait(SPAWN_SERVER *server __maybe_unused, SPAWN_INSTANCE *
1372 // get the result
1373 struct status_report sr = { 0 };
1374 if(read(instance->client_sock, &sr, sizeof(sr)) != sizeof(sr))
1360 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "SPAWN PARENT: failed to receive final status report for child %d, request %zu", instance->child_pid, instance->request_id);
1375 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
1376 + "SPAWN PARENT: failed to read final status report for child %d, request %zu",
1377 + instance->child_pid, instance->request_id);
1378
1379 + else if(sr.magic != STATUS_REPORT_MAGIC) {
1380 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
1381 + "SPAWN PARENT: invalid final status report for child %d, request %zu (invalid magic %#x in response)",
1382 + instance->child_pid, instance->request_id, sr.magic);
1383 + }
1384 else switch(sr.status) {
1385 case STATUS_REPORT_EXITED:
1386 rc = sr.exited.waitpid_status;
@@ -1368,7 +1390,9 @@ int spawn_server_exec_wait(SPAWN_SERVER *server __maybe_unused, SPAWN_INSTANCE *
1390 case STATUS_REPORT_FAILED:
1391 default:
1392 errno = 0;
1371 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "SPAWN PARENT: invalid status report to exec spawn request %zu for pid %d (status = %u)", instance->request_id, instance->child_pid, sr.status);
1393 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
1394 + "SPAWN PARENT: invalid status report to exec spawn request %zu for pid %d (status = %u)",
1395 + instance->request_id, instance->child_pid, sr.status);
1396 break;
1397 }
1398
@@ -1431,7 +1455,16 @@ SPAWN_INSTANCE* spawn_server_exec(SPAWN_SERVER *server, int stderr_fd, int custo
1455
1456 struct status_report sr = { 0 };
1457 if(read(instance->client_sock, &sr, sizeof(sr)) != sizeof(sr)) {
1434 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "SPAWN PARENT: Failed to exec spawn request %zu (cannot get initial status report)", request.request_id);
1458 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
1459 + "SPAWN PARENT: Failed to exec spawn request %zu (cannot get initial status report)",
1460 + request.request_id);
1461 + goto cleanup;
1462 + }
1463 +
1464 + if(sr.magic != STATUS_REPORT_MAGIC) {
1465 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
1466 + "SPAWN PARENT: Failed to exec spawn request %zu (invalid magic %#x in response)",
1467 + request.request_id, sr.magic);
1468 goto cleanup;
1469 }
1470
@@ -1442,13 +1475,17 @@ SPAWN_INSTANCE* spawn_server_exec(SPAWN_SERVER *server, int stderr_fd, int custo
1475
1476 case STATUS_REPORT_FAILED:
1477 errno = sr.failed.err_no;
1445 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "SPAWN PARENT: Failed to exec spawn request %zu (check errno #1)", request.request_id);
1478 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
1479 + "SPAWN PARENT: Failed to exec spawn request %zu (server reports failure, errno is updated)",
1480 + request.request_id);
1481 errno = 0;
1482 break;
1483
1484 case STATUS_REPORT_EXITED:
1485 errno = ENOEXEC;
1451 - nd_log(NDLS_COLLECTORS, NDLP_ERR, "SPAWN PARENT: Failed to exec spawn request %zu (check errno #2)", request.request_id);
1486 + nd_log(NDLS_COLLECTORS, NDLP_ERR,
1487 + "SPAWN PARENT: Failed to exec spawn request %zu (server reports exit, errno is updated)",
1488 + request.request_id);
1489 errno = 0;
1490 break;
1491