Skip to content

Commit

Permalink
Block io_uring without networking exception
Browse files Browse the repository at this point in the history
This patch blocks all `io_uring` syscalls when the sandbox does not have
full networking permissions.

Closes #32.
  • Loading branch information
cd-work committed Aug 28, 2023
1 parent cce1438 commit d3d296f
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/linux/seccomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ impl Filter {
self.rules.insert(libc::SYS_socketpair, socket_rule.clone());
self.rules.insert(libc::SYS_socket, socket_rule);

// Restrict io_uring.
self.rules.insert(libc::SYS_io_uring_setup, Vec::new());
self.rules.insert(libc::SYS_io_uring_enter, Vec::new());
self.rules.insert(libc::SYS_io_uring_register, Vec::new());

Ok(())
}

Expand Down
67 changes: 67 additions & 0 deletions tests/net.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#[cfg(target_os = "linux")]
use std::io::Error as IoError;
use std::io::ErrorKind as IoErrorKind;
use std::net::{TcpListener, TcpStream};

use birdcage::{Birdcage, Exception, Sandbox};
#[cfg(target_os = "linux")]
use libc;

#[test]
fn network() {
Expand All @@ -11,3 +16,65 @@ fn network() {
TcpStream::connect("8.8.8.8:443").unwrap();
TcpListener::bind("127.0.0.1:31337").unwrap();
}

#[cfg(target_os = "linux")]
#[test]
fn allow_io_uring() {
let mut birdcage = Birdcage::new().unwrap();
birdcage.add_exception(Exception::Networking).unwrap();
birdcage.lock().unwrap();

let mut io_uring_params =
vec![IoUringParams { flags: 1, sq_entries: 32, cq_entries: 32, ..Default::default() }];

let result = unsafe {
libc::syscall(libc::SYS_io_uring_setup, io_uring_params.len(), io_uring_params.as_mut_ptr())
};

assert_eq!(result >= 0);
}

#[cfg(target_os = "linux")]
#[test]
fn block_io_uring() {
let birdcage = Birdcage::new().unwrap();
birdcage.lock().unwrap();

let mut io_uring_params =
vec![IoUringParams { flags: 1, sq_entries: 32, cq_entries: 32, ..Default::default() }];

let result = unsafe {
libc::syscall(libc::SYS_io_uring_setup, io_uring_params.len(), io_uring_params.as_mut_ptr())
};

assert_eq!(result, -1);
assert_eq!(IoError::last_os_error().kind(), IoErrorKind::PermissionDenied);
}

#[repr(C)]
#[derive(Default)]
struct IoUringParams {
sq_entries: u32,
cq_entries: u32,
flags: u32,
sq_thread_cpu: u32,
sq_thread_idle: u32,
features: u32,
wq_fd: u32,
resv: [u32; 3],
sq_off: IoSqringOffsets,
cq_off: IoSqringOffsets,
}

#[repr(C)]
#[derive(Default)]
struct IoSqringOffsets {
head: u32,
tail: u32,
ring_mask: u32,
ring_entries: u32,
flags: u32,
dropped: u32,
array: u32,
resv: [u32; 3],
}

0 comments on commit d3d296f

Please sign in to comment.