FreeBSD's Capsicum facility is used to sandbox processes into a capability mode. Unable to access any global namespaces, their ability to harm the overall system is very limited. It's a terrific security feature. But the sysctl(3) functions do access global namespaces. So to use them in capability mode requires a helper: the Casper library. Once a process is in capability mode, it can use the cap_sysctl(3) facility to access sysctls. I originally attempted to implement cap_sysctl in a separate crate, but encountered difficulties. Basically, it's just way too complicated. Dealing with sysctls, as you know, requires lots of code to handle all the different data types. So instead of having a separate cap-sysctl-rs crate, I propose moving that functionality into here. If you agree, this is what I think we should do:
- Add libcasper(3) bindings to libc, or create a separate
libcasper-sys crate. I'll raise the issue with the libc team and see which they prefer.
- Implement basic
libcasper support within the capsicum-rs crate. I've already got a branch for this.
- Add a private
SysctlProvider trait to this crate with three methods: sysctlbyname, sysctl, and sysctlnametomib. Existing functions like unix::funcs::value_oid will gain a new argument, a &dyn SysctlProvider.
- Create two implementors of this trait:
NativeSysctlProvider and CasperSysctlProvider. The former will simply wrap the existing sysctl(3) functions. The latter will wrap cap_sysctl(3), and will also include methods to initialize the casper connection and configure limits.
- Create a public
CasperSysctl struct and implement the Sysctl trait for it. In order to preserve the existing API, the actual casper connection will have to be a global variable.
- Optionally, gate all of this Casper stuff behind a feature flag. However, since Casper is only implemented on FreeBSD and all official FreeBSD releases have it, I don't think we need to add a feature flag .
What do you think? cc @dlrobertson .
FreeBSD's Capsicum facility is used to sandbox processes into a capability mode. Unable to access any global namespaces, their ability to harm the overall system is very limited. It's a terrific security feature. But the sysctl(3) functions do access global namespaces. So to use them in capability mode requires a helper: the Casper library. Once a process is in capability mode, it can use the cap_sysctl(3) facility to access sysctls. I originally attempted to implement
cap_sysctlin a separate crate, but encountered difficulties. Basically, it's just way too complicated. Dealing with sysctls, as you know, requires lots of code to handle all the different data types. So instead of having a separatecap-sysctl-rscrate, I propose moving that functionality into here. If you agree, this is what I think we should do:libcasper-syscrate. I'll raise the issue with the libc team and see which they prefer.libcaspersupport within the capsicum-rs crate. I've already got a branch for this.SysctlProvidertrait to this crate with three methods:sysctlbyname,sysctl, andsysctlnametomib. Existing functions likeunix::funcs::value_oidwill gain a new argument, a&dyn SysctlProvider.NativeSysctlProviderandCasperSysctlProvider. The former will simply wrap the existingsysctl(3)functions. The latter will wrapcap_sysctl(3), and will also include methods to initialize the casper connection and configure limits.CasperSysctlstruct and implement theSysctltrait for it. In order to preserve the existing API, the actual casper connection will have to be a global variable.What do you think? cc @dlrobertson .