Skip to content

Commit e7a7fd0

Browse files
squellbjorn3
authored andcommitted
rewrite handle_notifications to be even more clear
1 parent d4d6c17 commit e7a7fd0

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

src/exec/noexec.rs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -87,26 +87,26 @@ fn alloc_notify_allocs() -> NotifyAllocs {
8787
}
8888
}
8989

90-
/// Returns 'false' if the ioctl failed with E_NOENT, 'true' if it succeeded.
90+
/// Returns 'None' if the ioctl failed with E_NOENT, 'Some(())' if it succeeded.
9191
/// This aborts the program in any other situation.
9292
///
9393
/// # Safety
9494
///
9595
/// `ioctl(fd, request, ptr)` must be safe to call
96-
unsafe fn ioctl<T>(fd: RawFd, request: libc::c_ulong, ptr: *mut T) -> bool {
96+
unsafe fn ioctl<T>(fd: RawFd, request: libc::c_ulong, ptr: *mut T) -> Option<()> {
9797
// SAFETY: By function contract
9898
if unsafe { libc::ioctl(fd, request, ptr) } == -1 {
9999
// SAFETY: Trivial
100100
if unsafe { *__errno_location() } == ENOENT {
101-
false
101+
None
102102
} else {
103103
// SAFETY: Not actually unsafe
104104
unsafe {
105105
libc::abort();
106106
}
107107
}
108108
} else {
109-
true
109+
Some(())
110110
}
111111
}
112112

@@ -120,37 +120,42 @@ unsafe fn handle_notifications(notify_fd: OwnedFd) -> ! {
120120
resp,
121121
} = alloc_notify_allocs();
122122

123-
// The first notification must be allowed to pass unhindered.
124-
let mut error = 0;
125-
let mut flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE as _;
126-
127-
loop {
123+
// SAFETY: See individual SAFETY comments
124+
let handle_syscall = |create_response: fn(&mut _)| unsafe {
128125
// SECCOMP_IOCTL_NOTIF_RECV expects the target struct to be zeroed
129126
// SAFETY: req is at least req_size bytes big.
130-
unsafe { std::ptr::write_bytes(req.cast::<u8>(), 0, req_size) };
127+
std::ptr::write_bytes(req.cast::<u8>(), 0, req_size);
131128

132129
// SAFETY: A valid pointer to a seccomp_notify is passed in; notify_fd is valid.
133-
if unsafe { !ioctl(notify_fd.as_raw_fd(), SECCOMP_IOCTL_NOTIF_RECV, req) } {
134-
continue;
135-
}
130+
ioctl(notify_fd.as_raw_fd(), SECCOMP_IOCTL_NOTIF_RECV, req)?;
136131

137132
// Allow the first execve call as this is sudo itself starting the target executable.
138133
// SAFETY: resp is a valid pointer to a seccomp_notify_resp.
139-
unsafe {
140-
(*resp).id = (*req).id;
141-
(*resp).val = 0;
142-
(*resp).error = error;
143-
(*resp).flags = flags;
144-
}
134+
(*resp).id = (*req).id;
135+
create_response(&mut *resp);
145136

146137
// SAFETY: A valid pointer to a seccomp_notify_resp is passed in; notify_fd is valid.
147-
if unsafe { !ioctl(notify_fd.as_raw_fd(), SECCOMP_IOCTL_NOTIF_SEND, resp) } {
148-
continue;
138+
ioctl(notify_fd.as_raw_fd(), SECCOMP_IOCTL_NOTIF_SEND, resp)
139+
};
140+
141+
loop {
142+
if handle_syscall(|resp| {
143+
resp.val = 0;
144+
resp.error = 0;
145+
resp.flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE as _
146+
})
147+
.is_some()
148+
{
149+
break;
149150
}
151+
}
150152

151-
// As soon as we have reached this point, all notifications will be acted upon.
152-
error = -EACCES;
153-
flags = 0;
153+
loop {
154+
handle_syscall(|resp| {
155+
resp.val = 0;
156+
resp.error = -EACCES;
157+
resp.flags = 0;
158+
});
154159
}
155160
}
156161

0 commit comments

Comments
 (0)