Skip to content

Commit 68b8809

Browse files
fix(tests): copy the runner, not /bin/cat, as the POSIX blocked image
daemon_runtime_process_fingerprint_never_hashes_replacement_path (POSIX variant) copied /bin/cat to a temp file named "image" and executed the copy. On Ubuntu 25.10+/26.04 and any other uutils system, /bin/cat is a multi-call binary: a copy invoked under the name "image" prints "coreutils: unknown program 'image'" and exits 1, so the fixture died at ASSERT(setup). Reproduced on WSL Ubuntu 26.04 (uutils coreutils 0.8.0). The Windows variant of the same test already avoids this class of donor: it copies the test runner itself and parks it in a __cbm_runtime_image_holder argv mode. The POSIX variant now does the same. The holder mode gains a POSIX branch that blocks reading stdin until EOF — exactly the behaviour the cat donor provided — and runtime_test_spawn_blocked_executable passes the holder argument, so its target must now be a copy of this runner (it has exactly one caller). The /bin/echo replacement donor is gone too: it was only ever hashed, never executed, and on a uutils system cat and echo can be the same multi-call bytes, which would have broken the fixture's original != replacement precondition. The replacement is now a small data file, mirroring the Windows variant. No signing change is needed on macOS: the image copy stays byte-identical to the runner, and the identical-copy fixture already proves such a copy executes. daemon_runtime suite on WSL Ubuntu 26.04: 44 passed / 0 failed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: OhOkThisIsFine <102485413+OhOkThisIsFine@users.noreply.github.com>
1 parent 997d087 commit 68b8809

2 files changed

Lines changed: 29 additions & 6 deletions

File tree

‎tests/test_daemon_runtime.c‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,9 @@ static bool runtime_test_copy_executable(const char *source, const char *destina
382382
return ok;
383383
}
384384

385+
/* PATH must be a copy of this runner: the child runs the
386+
* __cbm_runtime_image_holder mode, which blocks reading the release pipe
387+
* wired to its stdin. */
385388
static pid_t runtime_test_spawn_blocked_executable(const char *path, int *release_fd_out) {
386389
int ready[2] = {-1, -1};
387390
int input[2] = {-1, -1};
@@ -427,7 +430,7 @@ static pid_t runtime_test_spawn_blocked_executable(const char *path, int *releas
427430
if (input[0] != STDIN_FILENO) {
428431
(void)posix_spawn_file_actions_addclose(&actions, input[0]);
429432
}
430-
char *const child_argv[] = {(char *)path, NULL};
433+
char *const child_argv[] = {(char *)path, "__cbm_runtime_image_holder", NULL};
431434
pid_t child = -1;
432435
if (posix_spawn(&child, path, &actions, NULL, child_argv, environ) != 0) {
433436
child = -1;
@@ -4518,10 +4521,20 @@ TEST(daemon_runtime_process_fingerprint_never_hashes_replacement_path) {
45184521
int replacement_written =
45194522
setup ? snprintf(replacement_path, sizeof(replacement_path), "%s/replacement", directory)
45204523
: -1;
4524+
/* The copied image is this runner in holder mode, not a system utility:
4525+
* a multi-call coreutils /bin/cat (uutils) prints "unknown program" and
4526+
* exits when executed under the copied name. */
45214527
setup = setup && image_written > 0 && image_written < (int)sizeof(image_path) &&
45224528
replacement_written > 0 && replacement_written < (int)sizeof(replacement_path) &&
4523-
runtime_test_copy_executable("/bin/cat", image_path) &&
4524-
runtime_test_copy_executable("/bin/echo", replacement_path);
4529+
runtime_test_copy_self_image(image_path);
4530+
4531+
FILE *replacement_file = setup ? cbm_fopen(replacement_path, "wb") : NULL;
4532+
bool replacement_written_ok =
4533+
replacement_file && fputs("cbm-posix-replacement-image", replacement_file) >= 0;
4534+
if (replacement_file) {
4535+
replacement_written_ok = fclose(replacement_file) == 0 && replacement_written_ok;
4536+
}
4537+
setup = setup && replacement_written_ok;
45254538

45264539
char original[CBM_DAEMON_BUILD_FINGERPRINT_SIZE] = {0};
45274540
char replacement[CBM_DAEMON_BUILD_FINGERPRINT_SIZE] = {0};

‎tests/test_main.c‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,9 +503,19 @@ static int tf_maybe_run_runtime_image_holder(int argc, char **argv) {
503503
Sleep(INFINITE);
504504
return 25;
505505
#else
506-
(void)argc;
507-
(void)argv;
508-
return -1;
506+
/* POSIX copied-image holder: block reading stdin until the parent closes
507+
* the release pipe, exactly like the cat(1) donor this replaced. A system
508+
* utility cannot serve as the copied image — a multi-call coreutils
509+
* binary (uutils cat) refuses to execute under the copied name. */
510+
if (argc != 2 || strcmp(argv[1], "__cbm_runtime_image_holder") != 0) {
511+
return -1;
512+
}
513+
char release[16];
514+
ssize_t count;
515+
do {
516+
count = read(STDIN_FILENO, release, sizeof(release));
517+
} while (count > 0 || (count < 0 && errno == EINTR));
518+
return count == 0 ? 0 : 25;
509519
#endif
510520
}
511521

0 commit comments

Comments
 (0)