Skip to content

shmat_syscall misinterprets any attached user address ≥ 0x80000000 as an error #1076

@rishabhBudhouliya

Description

@rishabhBudhouliya

Bug

shmat_syscall misinterprets any attached user address ≥ 0x80000000 as an error, silently returning a bogus value and skipping the vmmap entry registration.

Root Cause

let result = vmmap.sys_to_user(result);
drop(vmmap);
// If the syscall succeeded, update the vmmap entry.
if result as i32 >= 0 {
// Ensure the syscall attached the segment at the expected address.
if result as u32 != useraddr {
panic!("shmat did not attach at the expected address");
}
let mut vmmap = cage.vmmap.write();
let backing = MemoryBackingType::SharedMemory(shmid as u64);
// Use the effective protection (prot) for both the current and maximum protection.
let maxprot = prot;
// Add a new vmmap entry for the shared memory segment.
// Since shared memory is not file-backed, there are no extra mapping flags
// or file offset parameters to consider; thus, we pass 0 for both.
vmmap
.add_entry_with_overwrite(
useraddr >> PAGESHIFT,
(rounded_length >> PAGESHIFT) as u32,
prot,
maxprot,
0, // No flags for shared memory mapping
backing,
0, // Offset is not applicable for shared memory
len as i64,
cageid,
)
.expect("shmat: failed to add vmmap entry");
} else {
// If the syscall failed, propagate the error.
return result as i32;

  • sys_to_user returns a full u32 wasm address (src/cage/src/memory/vmmap.rs:348).
  • result as i32 >= 0 is false for any user address with the top bit set (≥ 0x80000000).
  • The else branch returns the u32 as a negative i32, which glibc's shmat wrapper reinterprets as a pointer, so callers see a seemingly-valid return.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions