landlock-rs: fix narrow file grants silently dropped on regular files
ober
ab92be0fbf65a01f93520348fceddf002e68ac60
--- a/jerboa-native-rs/src/landlock.rs +++ b/jerboa-native-rs/src/landlock.rs @@ -146,8 +146,32 @@ pub extern "C" fn jerboa_landlock_add_path_rule( return -1; } + // Landlock rejects landlock_add_rule with EINVAL if any + // directory-only access bit (READ_DIR, MAKE_*, REMOVE_*, REFER) + // appears in a rule whose parent_fd refers to a regular file — + // silently dropping the entire grant. When the target is not a + // directory, mask access_mask down to file-applicable bits + // (EXECUTE | WRITE_FILE | READ_FILE | TRUNCATE | IOCTL_DEV). + let mut effective_access = access_mask; + let mut st: libc::stat = unsafe { std::mem::zeroed() }; + if unsafe { libc::fstat(parent_fd, &mut st) } == 0 + && (st.st_mode & libc::S_IFMT) != libc::S_IFDIR + { + const FILE_BITS: u64 = + (1u64 << 0) | // EXECUTE + (1u64 << 1) | // WRITE_FILE + (1u64 << 2) | // READ_FILE + (1u64 << 14) | // TRUNCATE + (1u64 << 15); // IOCTL_DEV + effective_access &= FILE_BITS; + } + if effective_access == 0 { + unsafe { libc::close(parent_fd); } + return 0; + } + let attr = LandlockPathBeneathAttr { - allowed_access: access_mask, + allowed_access: effective_access, parent_fd, }; let rc = unsafe {