65 lines
2.3 KiB
C
65 lines
2.3 KiB
C
// Diagnostic for the gnoExecProbe exec-into failure: distinguishes a PATH/
|
|
// access() resolution miss from a K_execve transfer-of-control failure.
|
|
// Runs in the SAME harness as gnoExecProbe (GNO_PROG2=gnoExeced deployed to
|
|
// /bin). Each marker isolates one step so we can see exactly where exec dies.
|
|
//
|
|
// Bank-2 absolute uint16 markers (DBR-independent):
|
|
// 0x025000 C0DE reached end (fallback; set only if every exec returned)
|
|
// 0x025010 E0EC gnoExeced ran -> some exec transferred control (success)
|
|
// 0x025020 F00D access("/bin/gnoexeced", F_OK) == 0 (our libc finds it)
|
|
// else EE00|errno (access failed -> which errno)
|
|
// 0x025022 EE00|errno after execv("/bin/gnoexeced") RETURNED (explicit path,
|
|
// bypasses PATH; only set if the exec failed to transfer)
|
|
// 0x025024 EE00|errno after execvp("gnoexeced") RETURNED (PATH-resolved;
|
|
// only set if that exec failed too)
|
|
#include <stdint.h>
|
|
|
|
extern int access(const char *path, int mode);
|
|
extern int execv(const char *path, char *const *argv);
|
|
extern int execvp(const char *file, char *const *argv);
|
|
extern int errno;
|
|
|
|
#define M(a) (*(volatile uint16_t *)(a))
|
|
#define BAD 0xDEAD
|
|
#define F_OK 0
|
|
|
|
|
|
int main(void) {
|
|
char *argv[2];
|
|
int r;
|
|
|
|
M(0x025000UL) = 0x0000;
|
|
M(0x025010UL) = BAD;
|
|
M(0x025020UL) = BAD;
|
|
M(0x025022UL) = BAD;
|
|
M(0x025024UL) = BAD;
|
|
|
|
argv[0] = "gnoexeced";
|
|
argv[1] = 0;
|
|
|
|
// Step 1: does our own access() see the file gsh clearly found at /bin?
|
|
errno = 0;
|
|
r = access("/bin/gnoexeced", F_OK);
|
|
if (r == 0) {
|
|
M(0x025020UL) = 0xF00D;
|
|
} else {
|
|
M(0x025020UL) = 0xEE00 | (uint16_t)(errno & 0xFF);
|
|
}
|
|
|
|
// Step 2: explicit-path execv (bypasses $PATH entirely). On success this
|
|
// never returns -- gnoExeced sets 0x025010 + 0x025000 in the same image.
|
|
errno = 0;
|
|
execv("/bin/gnoexeced", argv);
|
|
M(0x025022UL) = 0xEE00 | (uint16_t)(errno & 0xFF); // only if it returned
|
|
|
|
// Step 3: PATH-resolved execvp, as gnoExecProbe does.
|
|
errno = 0;
|
|
execvp("gnoexeced", argv);
|
|
M(0x025024UL) = 0xEE00 | (uint16_t)(errno & 0xFF); // only if it returned
|
|
|
|
// Reached only if BOTH execs failed to transfer control.
|
|
M(0x025000UL) = 0xC0DE;
|
|
for (volatile unsigned long j = 0; j < 300000UL; j++) {
|
|
}
|
|
return 0;
|
|
}
|