Skip to content

Commit 9da7715

Browse files
committed
Fix memcheck fork-child endpoint leaks
Free the inherited POSIX daemon endpoint in the three fork tests before their children call _exit. These losses were test artifacts, not product ownership bugs. Re-exec the user namespace probe using the runner path recorded from argv[0]. Under Valgrind, /proc/self/exe can resolve to the instrumentation executable, so the probe did not reliably start a fresh test-runner process to derive the namespace overflow uid. Re-executing the runner preserves the fresh-process check while allowing Valgrind to report the test result. Create build/ before allocating the temporary memory-analysis build directory so the script works on a fresh checkout.
1 parent f701caf commit 9da7715

2 files changed

Lines changed: 10 additions & 1 deletion

File tree

‎scripts/analyze-memory.sh‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ fi
2222

2323
RESULTS_DIR="${CBM_MEMORY_RESULTS_DIR:-$ROOT/memlab-memory-analysis}"
2424
RUN_ID="$(date +%Y%m%d-%H%M%S)-$$"
25+
mkdir -p "$ROOT/build"
2526
ANALYSIS_BUILD="$(mktemp -d "$ROOT/build/memory-analysis.XXXXXX")"
2627
TEST_BIN="$ANALYSIS_BUILD/test-runner"
2728
RUN_RESULTS="$RESULTS_DIR/$RUN_ID"

‎tests/test_daemon_ipc.c‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include <stdlib.h>
2626
#include <string.h>
2727

28+
extern const char *cbm_test_program_path;
29+
2830
#ifdef _WIN32
2931
#ifndef WIN32_LEAN_AND_MEAN
3032
#define WIN32_LEAN_AND_MEAN
@@ -3262,6 +3264,7 @@ TEST(daemon_ipc_posix_startup_lock_is_cross_process) {
32623264
int child_result = ipc_test_cross_process_lock_child(endpoint, commands[0], results[1]);
32633265
(void)close(commands[0]);
32643266
(void)close(results[1]);
3267+
cbm_daemon_ipc_endpoint_free(endpoint);
32653268
_exit(child_result);
32663269
}
32673270
if (child > 0) {
@@ -3352,6 +3355,7 @@ TEST(daemon_ipc_posix_lifetime_reservation_rejects_fork_inheritance) {
33523355
cbm_daemon_ipc_lifetime_reservation_release(inherited);
33533356
bool reported = ipc_test_fd_write_all(result_pipe[1], &child_result, sizeof(child_result));
33543357
(void)close(result_pipe[1]);
3358+
cbm_daemon_ipc_endpoint_free(endpoint);
33553359
_exit(reported && child_result == 1 ? 0 : 1);
33563360
}
33573361
if (child > 0) {
@@ -3447,6 +3451,7 @@ TEST(daemon_ipc_posix_child_participant_handoff_retains_legacy_bridge) {
34473451
ipc_test_fd_write_all(child_to_parent[1], &release_byte, sizeof(release_byte));
34483452
(void)close(parent_to_child[0]);
34493453
(void)close(child_to_parent[1]);
3454+
cbm_daemon_ipc_endpoint_free(endpoint);
34503455
_exit(join_byte == 1 && release_reported && release_byte == 1 ? 0 : 1);
34513456
}
34523457
if (child > 0) {
@@ -5581,7 +5586,10 @@ TEST(daemon_ipc_posix_single_uid_userns_real_smoke_issue1830) {
55815586
* unprivileged userns) -- while looking like a product regression.
55825587
* Re-exec so the decision is made by a process that STARTED here, which
55835588
* is also the only shape production ever takes. */
5584-
(void)execl("/proc/self/exe", "test-runner", "--userns-secure-probe", probe, (char *)NULL);
5589+
/* /proc/self/exe can name Valgrind itself here. Re-exec the runner
5590+
* path recorded from argv[0] so the probe starts fresh in the namespace. */
5591+
(void)execl(cbm_test_program_path, "test-runner", "--userns-secure-probe", probe,
5592+
(char *)NULL);
55855593
_exit(3); /* exec failed -- distinct from secure(0)/refused(1)/skip(2) */
55865594
}
55875595
if (child < 0) {

0 commit comments

Comments
 (0)