2
1

0001-Fix-use-of-uninitialized-exit-status.patch 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. From f6d56c374723923e276ccfd442fdd0cabf23d095 Mon Sep 17 00:00:00 2001
  2. From: Fiona Klute <fiona.klute@gmx.de>
  3. Date: Fri, 14 Feb 2025 19:26:24 +0100
  4. Subject: [PATCH] Fix use of uninitialized exit status
  5. Depending on the timing between the SIGCHLD callback run and the first
  6. generic_cb() timer callback run, script_exit_status() sometimes
  7. returned uninitialized memory as the exit status of a script. This
  8. could lead to incorrect "critical error" reports if that uninitialized
  9. memory happened to contain a value that interpreted as an int was
  10. above the critical threshold.
  11. Additionally, script_exit_status() unconditionally removed the process
  12. information from the queue, meaning that if a process had not
  13. completed by the time its status was first probed, its status could
  14. never be updated or successfully probed again, leading to timeout. Fix
  15. this by removing the process only if the status indicates it has
  16. terminated (successful or not).
  17. The problems affected primarily scripts running approximately one
  18. second or longer, because very short running scripts will very likely
  19. have their exit status collected by the SIGCHLD callback before the
  20. first timer callback run.
  21. Signed-off-by: Fiona Klute <fiona.klute@gmx.de>
  22. Upstream: https://github.com/troglobit/watchdogd/pull/52
  23. ---
  24. src/script.c | 13 ++++++++++---
  25. 1 file changed, 10 insertions(+), 3 deletions(-)
  26. diff --git a/src/script.c b/src/script.c
  27. index 1220fb9..f6e0763 100644
  28. --- a/src/script.c
  29. +++ b/src/script.c
  30. @@ -16,6 +16,7 @@
  31. */
  32. #include <errno.h>
  33. +#include <stdbool.h> /* bool type (before C23) */
  34. #include <stdlib.h> /* setenv() */
  35. #include <sys/wait.h> /* waitpid() */
  36. #include <unistd.h> /* execv(), _exit() */
  37. @@ -28,6 +29,7 @@
  38. struct exec_info {
  39. pid_t pid;
  40. int exit_status;
  41. + bool exited;
  42. void (*cb)(void *arg);
  43. void *arg;
  44. LIST_ENTRY(exec_info) entry;
  45. @@ -64,6 +66,8 @@ static void add(pid_t pid, void (*cb)(void *), void *arg)
  46. }
  47. info->pid = pid;
  48. + info->exit_status = 0;
  49. + info->exited = false;
  50. info->cb = cb;
  51. info->arg = arg;
  52. LIST_INSERT_HEAD(&exec_info_head, info, entry);
  53. @@ -78,6 +82,7 @@ static int exec(pid_t pid, int status)
  54. continue;
  55. info->exit_status = status;
  56. + info->exited = true;
  57. if (info->cb)
  58. info->cb(info->arg);
  59. @@ -96,9 +101,11 @@ int script_exit_status(pid_t pid)
  60. if (info->pid != pid)
  61. continue;
  62. - status = info->exit_status;
  63. - LIST_REMOVE(info, entry);
  64. - free(info);
  65. + if (info->exited) {
  66. + status = info->exit_status;
  67. + LIST_REMOVE(info, entry);
  68. + free(info);
  69. + }
  70. break;
  71. }
  72. --
  73. 2.47.2