Skip to content

Commit

Permalink
client: Add seccomp support
Browse files Browse the repository at this point in the history
  • Loading branch information
mbuesch committed Oct 18, 2024
1 parent b094a9d commit 86e9ab7
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions letmein/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,13 @@ letmein-conf = { workspace = true }
letmein-proto = { workspace = true }
tokio = { workspace = true, features = [ "rt", "net", "macros", ] }

[build-dependencies]
build-target = { workspace = true }

[target.'cfg(any(target_os="linux", target_os="android"))'.dependencies]
letmein-seccomp = { workspace = true, features = [ "de", "install" ] }

[target.'cfg(any(target_os="linux", target_os="android"))'.build-dependencies]
letmein-seccomp = { workspace = true, features = [ "compile", "ser" ] }

# vim: ts=4 sw=4 expandtab
47 changes: 47 additions & 0 deletions letmein/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// -*- coding: utf-8 -*-
//
// Copyright (C) 2024 Michael Büsch <m@bues.ch>
//
// Licensed under the Apache License version 2.0
// or the MIT license, at your option.
// SPDX-License-Identifier: Apache-2.0 OR MIT

#![forbid(unsafe_code)]
#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_variables)]

use build_target::target_arch;
use std::path::Path;

#[cfg(any(target_os = "linux", target_os = "android"))]
use letmein_seccomp::{Allow, Filter};

#[cfg(any(target_os = "linux", target_os = "android"))]
const SECCOMP_ALLOW_LIST: [Allow; 13] = [
Allow::Mmap,
Allow::Mprotect,
Allow::Open,
Allow::Read,
Allow::Write,
Allow::Fcntl { op: 0 }, //TODO
Allow::Stat,
Allow::Recv,
Allow::Send,
Allow::Listen,
Allow::TcpConnect,
Allow::Futex,
Allow::Uname,
];

fn main() {
let arch = target_arch().expect("Failed to get build target architecture");
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR is not set");

// Precompile the seccomp filters.
#[cfg(any(target_os = "linux", target_os = "android"))]
Filter::precompile(&SECCOMP_ALLOW_LIST, arch.as_str(), Path::new(&out_dir))
.expect("Failed to precompile seccomp BPF");
}

// vim: ts=4 sw=4 expandtab
47 changes: 47 additions & 0 deletions letmein/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,41 @@ use letmein_proto::UserId;
use std::{path::PathBuf, sync::Arc, time::Duration};
use tokio::runtime;

#[cfg(any(target_os = "linux", target_os = "android"))]
use letmein_conf::Seccomp;
#[cfg(any(target_os = "linux", target_os = "android"))]
use letmein_seccomp::{include_precompiled_filters, seccomp_supported, Filter as SeccompFilter};

/// Install the precompiled `seccomp` rules, if requested.
#[cfg(any(target_os = "linux", target_os = "android"))]
fn install_seccomp_rules(seccomp: Seccomp) -> ah::Result<()> {
if seccomp == Seccomp::Off {
return Ok(());
}

// See build.rs for the filter definition.
include_precompiled_filters!(SECCOMP_FILTER_KILL, SECCOMP_FILTER_LOG);
let filter_bytes = match seccomp {
Seccomp::Log => SECCOMP_FILTER_LOG,
Seccomp::Kill => SECCOMP_FILTER_KILL,
Seccomp::Off => unreachable!(),
};

// Install seccomp filter.
if seccomp_supported() {
SeccompFilter::deserialize(filter_bytes)
.install()
.context("Install seccomp filter")?;
} else {
eprintln!(
"WARNING: Not using seccomp. \
Letmein does not support seccomp on this architecture, yet."
);
}

Ok(())
}

#[derive(Parser, Debug)]
struct Opts {
/// Override the default path to the configuration file.
Expand All @@ -32,6 +67,14 @@ struct Opts {

#[command(subcommand)]
command: Command,

/// Override the `seccomp` setting from the configuration file.
///
/// If this option is not given, then the value
/// from the configuration file is used instead.
#[cfg(any(target_os = "linux", target_os = "android"))]
#[arg(long)]
seccomp: Option<Seccomp>,
}

impl Opts {
Expand Down Expand Up @@ -137,6 +180,10 @@ async fn async_main(opts: Opts) -> ah::Result<()> {
.context("Configuration file")?;
let conf = Arc::new(conf);

// Install `seccomp` rules, if required.
#[cfg(any(target_os = "linux", target_os = "android"))]
install_seccomp_rules(opts.seccomp.unwrap_or(conf.seccomp()))?;

// Run the user specified command.
match opts.command {
Command::Knock {
Expand Down

0 comments on commit 86e9ab7

Please sign in to comment.