From acacfc89f869ed9cadabdd41c9117586ddce4dc5 Mon Sep 17 00:00:00 2001 From: David Roundy Date: Sun, 10 Sep 2017 15:21:02 -0700 Subject: [PATCH 1/6] use pkg-config to identify the seccomp library --- Cargo.toml | 3 +++ build.rs | 11 +++++++++++ src/lib.rs | 1 - 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 build.rs diff --git a/Cargo.toml b/Cargo.toml index ed76a1e..f3abf1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,6 @@ readme = "README.md" [dependencies] libc = "0.2" + +[build-dependencies] +pkg-config = "^0.3.9" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..71ccdee --- /dev/null +++ b/build.rs @@ -0,0 +1,11 @@ +extern crate pkg_config; + +fn main() { + + if pkg_config::probe_library("libseccomp").is_err() { + // libseccomp is not installed as a system library... ideally + // we would like to build it from source, to make installation + // easier. + panic!("Need libseccomp library (with headers) to be installed!"); + } +} diff --git a/src/lib.rs b/src/lib.rs index f74ba92..b8746d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -109,7 +109,6 @@ pub struct scmp_arg_cmp { pub datum_b: scmp_datum_t, } -#[link(name = "seccomp")] extern { /** * Initialize the filter state From 6d020d9835ccc44417aebcb8a8884ed34a0de5d5 Mon Sep 17 00:00:00 2001 From: David Roundy Date: Mon, 11 Sep 2017 06:36:54 -0700 Subject: [PATCH 2/6] enable building even when libseccomp is not already installed --- .gitignore | 3 +++ Cargo.toml | 2 ++ build.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..16a4da0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +Cargo.lock +target +*~ diff --git a/Cargo.toml b/Cargo.toml index f3abf1d..349f102 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,5 @@ libc = "0.2" [build-dependencies] pkg-config = "^0.3.9" +curl = "^0.4.8" +gcc = "0.3" diff --git a/build.rs b/build.rs index 71ccdee..2ab6810 100644 --- a/build.rs +++ b/build.rs @@ -1,11 +1,78 @@ extern crate pkg_config; +extern crate curl; +extern crate gcc; + +use std::io::{Write}; + +use curl::easy::Easy; fn main() { - if pkg_config::probe_library("libseccomp").is_err() { + if pkg_config::probe_library("ibseccomp").is_err() { // libseccomp is not installed as a system library... ideally // we would like to build it from source, to make installation // easier. - panic!("Need libseccomp library (with headers) to be installed!"); + let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()); + + let mut tarball = std::fs::File::create(out_dir.join("libseccomp.tar.gz")).unwrap(); + let mut handle = Easy::new(); + handle.follow_location(true).unwrap(); + handle.url("https://github.com/seccomp/libseccomp/releases/download/v2.3.2/libseccomp-2.3.2.tar.gz").unwrap(); + handle.write_function(move |data| { + Ok(tarball.write(data).unwrap()) + }).unwrap(); + handle.perform().unwrap(); + + run("Trouble untarring source code", + std::process::Command::new("tar") + .args(&["xzf", "libseccomp.tar.gz"]) + .current_dir(&out_dir)); + + let build_dir = out_dir.join("libseccomp-2.3.2"); + let src_dir = build_dir.join("src"); + + // The following is an unholy hodge-podge of techniques. I + // use ./configure to generate the "config.h" file, which is + // used by the library. But sadly, I can't seem to get make + // to cross-compile libseccomp properly, even though I + // specified the --host argument to ./configure. So instead, + // I manually determine which files to compile, and then use + // the gcc crate, which *does* know how to cross-compile + // properly to do the actual building of the library. + let mut sources = Vec::new(); + for f in src_dir.read_dir() { + for f in f.flat_map(|f| f.ok()) { // lazy way to ignore errors + if f.path().extension() == Some(std::ffi::OsStr::new("c")) + && f.file_name() != std::ffi::OsStr::new("arch-syscall-check.c") + && f.file_name() != std::ffi::OsStr::new("arch-syscall-dump.c") { + sources.push(f.path()); + } + } + } + let prefix = out_dir.join("libseccomp"); + + let target = std::env::var("TARGET").unwrap(); + println!("target is {}", target); + run("Trouble configuring source code", + std::process::Command::new("./configure") + .args(&["--enable-shared=no", "--disable-dependency-tracking", + "--prefix",]) + .arg(prefix) + .arg("--host") + .arg(target) + .current_dir(&build_dir)); + + gcc::Build::new() + .files(sources) + .include(&src_dir) + .include(&build_dir) + .include(build_dir.join("include")) + .compile("libseccomp.a"); + } +} + +fn run(error_msg: &'static str, cmd: &mut std::process::Command) { + if !cmd.status().expect(error_msg).success() { + panic!(error_msg); } } From 6e13d61661186d31937a949621390fb23e5d30a6 Mon Sep 17 00:00:00 2001 From: David Roundy Date: Mon, 11 Sep 2017 06:39:31 -0700 Subject: [PATCH 3/6] fix typo that I had introduced to test the non-installed case --- build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.rs b/build.rs index 2ab6810..b7d73a5 100644 --- a/build.rs +++ b/build.rs @@ -8,7 +8,7 @@ use curl::easy::Easy; fn main() { - if pkg_config::probe_library("ibseccomp").is_err() { + if pkg_config::probe_library("libseccomp").is_err() { // libseccomp is not installed as a system library... ideally // we would like to build it from source, to make installation // easier. From c0a7fd11ecd5a6b8eee43c0fa9ab82270a335f3e Mon Sep 17 00:00:00 2001 From: David Roundy Date: Tue, 12 Sep 2017 10:07:12 -0700 Subject: [PATCH 4/6] switch to submodule approach for building from source --- .gitmodules | 3 +++ Cargo.toml | 1 - build.rs | 78 ++++++++++++++++++++--------------------------------- libseccomp | 1 + 4 files changed, 33 insertions(+), 50 deletions(-) create mode 100644 .gitmodules create mode 160000 libseccomp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d580103 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libseccomp"] + path = libseccomp + url = https://github.com/seccomp/libseccomp.git diff --git a/Cargo.toml b/Cargo.toml index 349f102..32d0c30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,5 +13,4 @@ libc = "0.2" [build-dependencies] pkg-config = "^0.3.9" -curl = "^0.4.8" gcc = "0.3" diff --git a/build.rs b/build.rs index b7d73a5..57987c3 100644 --- a/build.rs +++ b/build.rs @@ -1,41 +1,21 @@ extern crate pkg_config; -extern crate curl; extern crate gcc; -use std::io::{Write}; - -use curl::easy::Easy; +use std::io::{Read,Write}; fn main() { if pkg_config::probe_library("libseccomp").is_err() { - // libseccomp is not installed as a system library... ideally - // we would like to build it from source, to make installation - // easier. - let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()); - - let mut tarball = std::fs::File::create(out_dir.join("libseccomp.tar.gz")).unwrap(); - let mut handle = Easy::new(); - handle.follow_location(true).unwrap(); - handle.url("https://github.com/seccomp/libseccomp/releases/download/v2.3.2/libseccomp-2.3.2.tar.gz").unwrap(); - handle.write_function(move |data| { - Ok(tarball.write(data).unwrap()) - }).unwrap(); - handle.perform().unwrap(); - - run("Trouble untarring source code", - std::process::Command::new("tar") - .args(&["xzf", "libseccomp.tar.gz"]) - .current_dir(&out_dir)); + // libseccomp is not installed as a system library... We thus + // need to build it from source. + if !std::path::Path::new("libseccomp/.git").exists() { + let _ = std::process::Command::new("git") + .args(&["submodule", "update", "--init"]) + .status(); + } - let build_dir = out_dir.join("libseccomp-2.3.2"); - let src_dir = build_dir.join("src"); + let src_dir = std::path::Path::new("libseccomp/src"); - // The following is an unholy hodge-podge of techniques. I - // use ./configure to generate the "config.h" file, which is - // used by the library. But sadly, I can't seem to get make - // to cross-compile libseccomp properly, even though I - // specified the --host argument to ./configure. So instead, // I manually determine which files to compile, and then use // the gcc crate, which *does* know how to cross-compile // properly to do the actual building of the library. @@ -49,30 +29,30 @@ fn main() { } } } - let prefix = out_dir.join("libseccomp"); - - let target = std::env::var("TARGET").unwrap(); - println!("target is {}", target); - run("Trouble configuring source code", - std::process::Command::new("./configure") - .args(&["--enable-shared=no", "--disable-dependency-tracking", - "--prefix",]) - .arg(prefix) - .arg("--host") - .arg(target) - .current_dir(&build_dir)); + // I create an empty file named config.h, since libseccomp + // doesn't actually require anything in the config.h, just + // that it exist. + let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()); + std::fs::File::create(out_dir.join("configure.h")).unwrap(); + + let mut header_in = std::fs::File::open(src_dir.join("../include/seccomp.h.in")).unwrap(); + let mut contents = String::new(); + header_in.read_to_string(&mut contents) + .expect("something went wrong reading the seccomp.h.in"); + let contents = contents.replace("@VERSION_MAJOR@", "2"); + let contents = contents.replace("@VERSION_MINOR@", "3"); + let contents = contents.replace("@VERSION_MICRO@", "2"); + { + let mut header_out = std::fs::File::create(out_dir.join("seccomp.h")).unwrap(); + write!(header_out, "{}", contents).unwrap(); + } gcc::Build::new() .files(sources) + .include(&out_dir) .include(&src_dir) - .include(&build_dir) - .include(build_dir.join("include")) + .include(src_dir.join("..")) + .include(src_dir.join("../include")) .compile("libseccomp.a"); } } - -fn run(error_msg: &'static str, cmd: &mut std::process::Command) { - if !cmd.status().expect(error_msg).success() { - panic!(error_msg); - } -} diff --git a/libseccomp b/libseccomp new file mode 160000 index 0000000..9b01871 --- /dev/null +++ b/libseccomp @@ -0,0 +1 @@ +Subproject commit 9b01871813cae608dcab455098b83488fa4cf65f From 4691e91f647ce45e69b81f5482e053254fb047d0 Mon Sep 17 00:00:00 2001 From: David Roundy Date: Sun, 11 Mar 2018 13:41:16 -0700 Subject: [PATCH 5/6] make fork official --- Cargo.toml | 6 +++--- README.md | 12 +++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 32d0c30..c84b7e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [package] -name = "seccomp-sys" +name = "seccomp-droundy-sys" version = "0.1.2" -authors = ["Alexander Polakov "] +authors = ["Alexander Polakov ", "David Roundy "] license = "LGPL-2.1" keywords = ["linux", "seccomp"] description = "low-level bindings to libseccomp" -repository = "https://github.com/polachok/seccomp-sys" +repository = "https://github.com/droundy/seccomp-sys" readme = "README.md" [dependencies] diff --git a/README.md b/README.md index 9516dae..b05263f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ -seccomp-sys ------------ +seccomp-droundy-sys +------------------- -Raw bindings to libseccomp. Requires [libseccomp](https://github.com/seccomp/libseccomp) to be installed. +Raw bindings to libseccomp. Does not require +[libseccomp](https://github.com/seccomp/libseccomp) to be installed, +but instead compiles it from source if it is not installed. -This library provides a high level interface to constructing, analyzing and installing seccomp filters via a BPF passed to the Linux Kernel's prctl() syscall. +This is a fork of https://github.com/polachok/seccomp-sys. -[Documentation](http://plhk.ru/static/doc/seccomp-sys/seccomp_sys/index.html) +This library provides a high level interface to constructing, analyzing and installing seccomp filters via a BPF passed to the Linux Kernel's prctl() syscall. From 946740621d47c880a9bb1c17031a50940634d217 Mon Sep 17 00:00:00 2001 From: David Roundy Date: Sun, 11 Mar 2018 13:46:27 -0700 Subject: [PATCH 6/6] fix bug in test --- examples/kill-setuid.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/kill-setuid.rs b/examples/kill-setuid.rs index 9cff181..9c194ba 100644 --- a/examples/kill-setuid.rs +++ b/examples/kill-setuid.rs @@ -1,19 +1,19 @@ extern crate libc; -extern crate seccomp_sys; +extern crate seccomp_droundy_sys; fn main() { unsafe { - let context = seccomp_sys::seccomp_init(seccomp_sys::SCMP_ACT_ALLOW); - let comparator = seccomp_sys::scmp_arg_cmp { + let context = seccomp_droundy_sys::seccomp_init(seccomp_droundy_sys::SCMP_ACT_ALLOW); + let comparator = seccomp_droundy_sys::scmp_arg_cmp { arg: 0, - op: seccomp_sys::scmp_compare::SCMP_CMP_EQ, + op: seccomp_droundy_sys::scmp_compare::SCMP_CMP_EQ, datum_a: 1000, datum_b: 0, }; /* arg[0] equals 1000 */ let syscall_number = 105; /* setuid on x86_64 */ - assert!(seccomp_sys::seccomp_rule_add(context, seccomp_sys::SCMP_ACT_KILL, syscall_number, 1, comparator) == 0); - assert!(seccomp_sys::seccomp_load(context) == 0); + assert!(seccomp_droundy_sys::seccomp_rule_add(context, seccomp_droundy_sys::SCMP_ACT_KILL, syscall_number, 1, comparator) == 0); + assert!(seccomp_droundy_sys::seccomp_load(context) == 0); assert!(libc::setuid(1000) == 0); /* process would be killed here */ } }