1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
//! A dirty module-loading library for the Linux kernel. //! //! This abuses Linux modules auto-loading mechanism to trick //! the kernel into shelling out to the userspace `modprobe` //! helper. //! //! A [side-effect][dev_load] of `SIOCGIFINDEX` ioctl results in //! the kernel looking up and loading arbitrary modules by name. //! This isn't strictly a privilege escalation as the caller must //! have `CAP_SYS_MODULE` capability; however it allows containerized //! process to load modules in the host namespace. //! //! This is a dirty mechanism, as the ioctl syscall will induce a //! context-switch back from kernel-space to user-space to run //! a host binary outside of caller context. //! //! Typically this results in `modprobe` being called in the host, //! however arbitrary binaries can be run by tweaking the usermode //! helper sysctl at `/proc/sys/kernel/modprobe`. //! //! [dev_load]: https://github.com/torvalds/linux/blob/v4.12/net/core/dev_ioctl.c#L372 extern crate nix; use std::ffi::CStr; use nix::net::if_::if_nametoindex; /// Try to load a host kernel module via the modprobe userspace helper. /// /// This triggers a `modprobe` execution in the host namespace. /// Caller must have the `CAP_SYS_MODULE` capability in order to /// load a module. There is no way to know if the module has been /// properly loaded, as the kernel does not return such information. pub fn try_load(module: &CStr) -> () { let _ = if_nametoindex(module); }