cube(2): read the errno from the libc, not from the syscall return value
glibc's syscall() returns -1 for *any* negative kernel return and stores the real errno separately, so `-ret` on the error path is always 1 — EPERM. KernelStore::call was computing `from_raw_os_error(-ret)`, so an absent record (the kernel's -ENOENT) came back as "Operation not permitted". That is why it hid this long: it only fires on the error path, and every early gate read records that existed. It is also what the sealer's EPERM was hours ago — not Morton codes, not a stray probe write; this. The fix reads std::io::Error::last_os_error() when the syscall returns -1, which is what libc left in errno. Proven by the encryption gate, which exercises exactly the missing-record path (keys reads an absent keystore cell first): PASS, with a sealed envelope on the device and no plaintext.
This commit is contained in:
@@ -92,9 +92,16 @@ impl KernelStore {
|
||||
// SAFETY: `syscall` is the libc entry point. The number is ours, there is exactly one
|
||||
// argument, and it points at `args`, which outlives the call. The kernel copies
|
||||
// everything it needs out of that structure and validates it.
|
||||
//
|
||||
// The errno is read from the libc, not from the return value: glibc's `syscall()` returns
|
||||
// `-1` for *any* negative kernel return and stores the real errno in `errno`, so `-ret`
|
||||
// here is always `1` (EPERM) on the error path. That mis-mapping turned an absent record
|
||||
// (the kernel's `-ENOENT`) into "Operation not permitted" — which is how it stayed hidden
|
||||
// this long: it only fires on the error path, and every early gate read records that
|
||||
// existed.
|
||||
let ret = unsafe { syscall(SYS_CUBE, args.op, args as *mut CubeArgs) };
|
||||
if ret < 0 {
|
||||
return Err(StoreError::Io(std::io::Error::from_raw_os_error((-ret) as i32)));
|
||||
if ret == -1 {
|
||||
return Err(StoreError::Io(std::io::Error::last_os_error()));
|
||||
}
|
||||
Ok(ret as u64)
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user