Rust bindings for the FreeBSD capsicum framework

Overview

capsicum

Current Version

Contain the awesome!

Rust bindings for the FreeBSD capsicum framework for OS capability and sandboxing

Prerequisites

Rust, Cargo, and FreeBSD.

Note: This currently only compiles on FreeBSD

Getting Started

Get the code

git clone https://github.com/danlrobertson/capsicum-rs
cd capsicum-rs
cargo build

Writing code using capsicum-rs

Entering capability mode

    use capsicum::{enter, sandboxed};
    use std::fs::File;
    use std::io::Read;

    let mut ok_file = File::open("/tmp/foo").unwrap();
    let mut s = String::new();

    enter().expect("enter failed!");
    assert!(sandboxed(), "application is not sandboxed!");

    match File::create("/tmp/cant_touch_this") {
        Ok(_) => panic!("application is not properly sandboxed!"),
        Err(e) => println!("properly sandboxed: {:?}", e)
    }

    match ok_file.read_to_string(&mut s) {
        Ok(_) => println!("This is okay since we opened the descriptor before sandboxing"),
        Err(_) => panic!("application is not properly sandboxed!")
    }

Limit capability rights to files

    use capsicum::{CapRights, Right, RightsBuilder};
    use std::fs::File;
    use std::io::Read;

    let x = rand::random::<bool>();
    
    let mut ok_file = File::open("/tmp/foo").unwrap();
    let mut s = String::new();
    
    let mut builder = RightsBuilder::new(Right::Seek);
    
    if x {
        builder.add(Right::Read);
    }

    let rights = builder.finalize().unwrap();

    rights.limit(&ok_file).unwrap();
    
    match ok_file.read_to_string(&mut s) {
        Ok(_) if x => println!("Allowed reading: x = {} ", x),
        Err(_) if !x => println!("Did not allow reading: x = {}", x),
        _ => panic!("Not properly sandboxed"),
    }
Comments
  • Feature Request: Add support for directories

    Feature Request: Add support for directories

    In https://github.com/myfreeweb/rusty-sandbox there is support for defining a Directory containing a path under which all associated operations can be permitted (e.g. allow read of everything under /zdata/files). This functionality would be a nice addition to this crate.

    Use case: combine with CAP_CONNECT to create a file downloader which can only write to specific directories (thinking of things like freebsd-update here :smirk:), or only permit an Iron/Nickel web server to read data from one location.

    opened by pwrdwnsys 5
  • Add a `rustfmt` Ci task

    Add a `rustfmt` Ci task

        It would be nice to have a `rustfmt` task as well, but we can do this in a follow up since it requires a `cargo fmt` run.
    

    Originally posted by @dlrobertson in https://github.com/dlrobertson/capsicum-rs/pull/12#discussion_r1020256852

    opened by dlrobertson 2
  • Multiple fixes and cleanup

    Multiple fixes and cleanup

    • clippy cleanup
    • enter and get_mode now return a io::Result
    • Fix a stack overflow in IoctlRights::from_file
    • Fix FFI bindings
    • Add a test for unlimited ioctl rights
    • Fix doc tests
    • Fix definitions of fork() and wait()
    opened by asomers 2
  • Move all FFI definitions out of this crate

    Move all FFI definitions out of this crate

    It's best practice to put FFI bindings in a separate crate, named *-sys. We should do something like that for capsicum. https://doc.rust-lang.org/cargo/reference/build-scripts.html#-sys-packages

    Futhermore, since Capsicum is part of FreeBSD's system C library, the correct place for these declarations is in the libc crate. That crate has the added advantage of a very good test suite to verify that the FFI functions are defined correctly. Therefore we should rely on libc's bindings. It already has bindings for most of Capsicum's functions.

    opened by asomers 1
  • In the tests, correctly check if a child process paniced

    In the tests, correctly check if a child process paniced

    • Must check the child process's exit status
    • Must switch the panic handler to SIGABRT, since stack unwinding isn't safe after fork() (requires nightly).
    opened by asomers 0
  • Improve test_basic_dir test

    Improve test_basic_dir test

    We could use tempdir to create a directory which we wouldn't have access to, or do something like a lookup in "./tests". We probably should avoid using "./src" and "./tests" which I think wouldn't work in some cases if the tests binary was run manually outside of the root crate directory.

    Originally posted by @dlrobertson in https://github.com/dlrobertson/capsicum-rs/pull/7#discussion_r1016017038

    Also see https://github.com/dlrobertson/capsicum-rs/pull/7/files#r1016042775

    opened by dlrobertson 0
  • Improvements to the integration tests:

    Improvements to the integration tests:

    • Use the tempfile crate instead of hard-coding temporary file names
    • Must use _exit(0) at the end of child processes, so we don't run the Rust destructors in both children and parents.
    • Minimize use of unsafe
    • Always run cap_enter in a child process.
    opened by asomers 0
  • IoctlRights can't represent

    IoctlRights can't represent "unlimited"

    If no limits have been placed on a file with cap_ioctls_limit, then cap_ioctls_get will return the special value CAP_IOCTLS_ALL, which means "unlimited". But IoctlRights has no way to represent that, since it's defined a as a vec of allowed commands.

    opened by asomers 0
  • test_ioctl fails with SIGABRT

    test_ioctl fails with SIGABRT

    On FreeBSD 14.0-CURRENT with a recent nightly rust, the ioctl test triggers an assertion within jemalloc

    > rustc --version
    rustc 1.67.0-nightly (215e3cd21 2022-11-03)
    > cargo test --test lib base::test_ioctl
    warning: use of deprecated macro `try`: use the `?` operator instead
      --> src/util.rs:47:20
       |
    47 |         let file = try!(File::open(path));
       |                    ^^^
       |
       = note: `#[warn(deprecated)]` on by default
    
    warning: `capsicum` (lib) generated 1 warning
        Finished test [unoptimized + debuginfo] target(s) in 0.06s
         Running tests/lib.rs (target/debug/deps/lib-23b06746adb64d7f)
    
    running 1 test
    <jemalloc>: /usr/home/somers/src/freebsd.org/src/contrib/jemalloc/include/jemalloc/internal/extent_inlines.h:65: Failed assertion: "szind < SC_NSIZES"
    error: test failed, to rerun pass `--test lib`
    
    Caused by:
      process didn't exit successfully: `/usr/home/somers/src/rust/capsicum-rs/target/debug/deps/lib-23b06746adb64d7f 'base::test_ioctl'` (signal: 6, SIGABRT: process abort signal)
    
    opened by asomers 0
  • Replace CapErr with io::Error

    Replace CapErr with io::Error

    CapErr simply served to wrap an io::Error around an enum that mainly just served to tell the user what function he had just called. But the user already knew that. Simpler just to return io::Error directly. The only complication was Directory::open_file, which needs to handle a NulError. I mapped that to io::Error with an ErrorKind of Other.

    Fixes #25

    opened by asomers 0
  • Use I/O Safety

    Use I/O Safety

    Rust 1.63.0 introduces I/O safety. RawFd (just a wrapper around i32) gets replaced by OwnedFd to track file ownership. It's a very nice improvement, and I think capscium should take advantage. https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html#rust-ownership-for-raw-file-descriptorshandles-io-safety

    opened by asomers 1
  • Needs Casper bindings

    Needs Casper bindings

    Capsicum's model is to block access to global namespaces. But important operations like gethostbynbame and sysctlbyname operate on global namespaces only. So to sandbox that, Capsicum uses the technique of privilege separation. Through libcasper(3) it forks child processes to deal with stuff like that. We should provide bindings for libcasper and the most important casper services. I've already got a start on this.

    enhancement 
    opened by asomers 1
  • Rethink error types

    Rethink error types

    I find CapErr to be confusing. Every type wraps either io::Error or ffi::NulError. The variants mainly serve to tell the user which function returned the error. But the user already knows that. I propose that we use plain io::Result for all functions whose inner error type is an io::Error. And for the few functions with more complicated error types we'll make an enum for each one. That's essentially the approach we take in the Nix crate.

    opened by asomers 0
  • Current docs are atrocious

    Current docs are atrocious

    • [ ] the purpose of the crate and use cases should be highlighted
    • [ ] documentation should contain less code and more descriptions
    • [ ] add docs to all the things
    • [ ] add #![deny(missing_docs)] to src/lib.rs
    opened by dlrobertson 2
Owner
Dan Robertson
Dan Robertson
Rust bindings to Linux Control Groups (cgroups)

cgroups-fs Native Rust library for managing Linux Control Groups (cgroups). This crate, curently, only supports the original, V1 hierarchy. You are we

Vlad Frolov 28 Nov 21, 2022
nginx bindings for Rust

nginx-rs This crate provides nginx bindings for Rust. Currently, only Linux is supported. How to Use Add nginx crate to Cargo.toml [dependencies] ngin

ArvanCloud 104 Jan 2, 2023
Rust bindings for iptables

Rust iptables This crate provides bindings for iptables application in Linux (inspired by go-iptables). This crate uses iptables binary to manipulate

Navid 63 Nov 17, 2022
Rust friendly bindings to *nix APIs

Rust bindings to *nix APIs Documentation (Releases) Nix seeks to provide friendly bindings to various *nix platform APIs (Linux, Darwin, ...). The goa

null 2k Jan 4, 2023
Rust bindings to Windows API

winapi-rs Documentation Official communication channel: #windows-dev on the Rust Community Discord This crate provides raw FFI bindings to all of Wind

Peter Atashian 1.6k Jan 1, 2023
Idiomatic inotify wrapper for the Rust programming language

inotify-rs Idiomatic inotify wrapper for the Rust programming language. extern crate inotify; use std::env; use inotify::{ EventMask, Watch

Hanno Braun 220 Dec 26, 2022
Rust library for filesystems in userspace (FUSE)

Rust FUSE - Filesystem in Userspace About fuse-rs is a Rust library crate for easy implementation of FUSE filesystems in userspace. fuse-rs does not j

Andreas Neuhaus 916 Jan 9, 2023
Freebsd-embedded-hal - Like linux-embedded-hal but FreeBSD

freebsd-embedded-hal Implementation of embedded-hal traits for FreeBSD devices: gpio: using libgpio, with stateful and toggleable support, with suppor

null 2 Oct 1, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
Rust implementation of a FreeBSD jail library

libjail-rs libjail-rs aims to be a rust implementation of the FreeBSD jail(3) library. While feature parity is a goal, a one-to-one implementation of

fubarnetes 38 Sep 27, 2022
Safe Rust bindings to the DynamoRIO dynamic binary instrumentation framework.

Introduction The dynamorio-rs crate provides safe Rust bindings to the DynamoRIO dynamic binary instrumentation framework, essentially allowing you to

S.J.R. van Schaik 17 Nov 21, 2022
Rust bindings to the dos-like framework

dos-like for Rust   This project provides access to Mattias Gustavsson's dos-like framework, so as to write DOS-like applications in Rust. How to use

Eduardo Pinho 9 Aug 25, 2022
Bindings to the macOS Security.framework

macOS/iOS Security framework for Rust Documentation Bindings to the Apple's Security.framework. Allows use of TLS and Keychain from Rust. License Lice

Kornel 172 Dec 24, 2022
Bindings to the macOS Security.framework

macOS/iOS Security framework for Rust Documentation Bindings to the Apple's Security.framework. Allows use of TLS and Keychain from Rust. License Lice

Kornel 172 Jan 2, 2023
A (flash) message framework for actix-web. A port to Rust of Django's message framework.

actix-web-flash-messages Flash messages for actix-web Web applications sometimes need to show a one-time notification to the user - e.g. an error mess

Luca Palmieri 31 Dec 29, 2022
Glommio Messaging Framework (GMF) is a high-performance RPC system designed to work with the Glommio framework.

Glommio Messaging Framework (GMF) The GMF library is a powerful and innovative framework developed for facilitating Remote Procedure Calls (RPCs) in R

Mohsen Zainalpour 29 Jun 13, 2023
An esoteric language/compiler written with Rust and Rust LLVM bindings

MeidoLang (メイドラング) A not so useful and esoteric language. The goal of this project was to contain some quirky or novel syntax in a stack-style program

null 0 Dec 24, 2021
Rust bindings for libinjection

libinjection-rs Rust bindings for libinjection. How to use Add libinjection to dependencies of Cargo.toml: libinjection = "0.2" Import crate: extern c

ArvanCloud 35 Sep 24, 2022
A project for generating C bindings from Rust code

cbindgen   Read the full user docs here! cbindgen creates C/C++11 headers for Rust libraries which expose a public C API. While you could do this by h

Ryan Hunt 1.7k Jan 3, 2023