93 lines
2.7 KiB
C
93 lines
2.7 KiB
C
// errno-space consistency probe for GNO/ME. The composite happy-path test
|
|
// proves the subsystems compose; this one hunts the KNOWN latent hazard: the
|
|
// fd layer maps GS/OS errors to POSIX errno via _mapErr, but the stat/exec/
|
|
// access wrappers stash the RAW kernel errno. A real program that branches on
|
|
// `errno == ENOENT` breaks wherever the raw value leaks through. We trigger the
|
|
// SAME logical error (a missing file) through four wrappers and record the raw
|
|
// errno each sets, so the divergence (if any) is visible against ENOENT.
|
|
//
|
|
// Bank-2 absolute uint16 markers (DBR-independent):
|
|
// 0x025000 C0DE reached end
|
|
// 0x025030 ENOENT (from errno.h) -- the value a POSIX app expects
|
|
// 0x025032 errno after open("nosuch", O_RDONLY) [fd layer, _mapErr]
|
|
// 0x025034 errno after stat("nosuch") [stat wrapper, raw kernel]
|
|
// 0x025036 errno after unlink("nosuch") [fd layer, _mapErr]
|
|
// 0x025038 errno after access("nosuch", F_OK) [access over stat]
|
|
// 0x02503A 0001 if all four calls actually FAILED (rc==-1), else which passed
|
|
// 0x02503C 0001 if every failing errno == ENOENT (POSIX-consistent), else DEAD
|
|
#include <stdint.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
|
|
#define M(a) (*(volatile uint16_t *)(a))
|
|
#define OK 0x0001
|
|
#define BAD 0xDEAD
|
|
|
|
static const char kMissing[] = "nosuchfile.xyz";
|
|
|
|
|
|
int main(void) {
|
|
struct stat sb;
|
|
uint16_t failed;
|
|
uint16_t consistent;
|
|
int eOpen;
|
|
int eStat;
|
|
int eUnlink;
|
|
int eAccess;
|
|
int rc;
|
|
int fd;
|
|
|
|
M(0x025000UL) = 0x0000;
|
|
|
|
M(0x025030UL) = (uint16_t)ENOENT; // what a POSIX app checks against
|
|
|
|
failed = OK;
|
|
|
|
errno = 0;
|
|
fd = open(kMissing, O_RDONLY);
|
|
eOpen = errno;
|
|
if (fd != -1) {
|
|
failed = BAD; // unexpectedly succeeded
|
|
close(fd);
|
|
}
|
|
M(0x025032UL) = (uint16_t)eOpen;
|
|
|
|
errno = 0;
|
|
rc = stat(kMissing, &sb);
|
|
eStat = errno;
|
|
if (rc != -1) {
|
|
failed = BAD;
|
|
}
|
|
M(0x025034UL) = (uint16_t)eStat;
|
|
|
|
errno = 0;
|
|
rc = unlink(kMissing);
|
|
eUnlink = errno;
|
|
if (rc != -1) {
|
|
failed = BAD;
|
|
}
|
|
M(0x025036UL) = (uint16_t)eUnlink;
|
|
|
|
errno = 0;
|
|
rc = access(kMissing, F_OK);
|
|
eAccess = errno;
|
|
if (rc != -1) {
|
|
failed = BAD;
|
|
}
|
|
M(0x025038UL) = (uint16_t)eAccess;
|
|
|
|
M(0x02503AUL) = failed;
|
|
|
|
consistent = OK;
|
|
if (eOpen != ENOENT || eStat != ENOENT || eUnlink != ENOENT || eAccess != ENOENT) {
|
|
consistent = BAD;
|
|
}
|
|
M(0x02503CUL) = consistent;
|
|
|
|
M(0x025000UL) = 0xC0DE;
|
|
for (volatile unsigned long j = 0; j < 300000UL; j++) {
|
|
}
|
|
return 0;
|
|
}
|