Skip to content

Commit

Permalink
Limit permissions for Android images.
Browse files Browse the repository at this point in the history
Remove the use of the `--privileged` flag for Android images and instead use an seccomp permissions. The provided profile is derived from the docker documentation, with slight modifications to allow `clone` and `clone3`.

The documentation is [docker seccomp](https://docs.docker.com/engine/security/seccomp/#significant-syscalls-blocked-by-the-default-profile), which details the syscalls blocked by docker. The same is true for podman. We merely modified these settings to allow `personality` syscall, which then allows us to use our Android images.
  • Loading branch information
Alexhuszagh committed Jun 3, 2022
1 parent ee4df2b commit 4888d06
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed

- #747 - reduced android image sizes.
- #746 - limit image permissions for android images.
- #377 - update WINE versions to 7.0.
- #734 - patch `arm-unknown-linux-gnueabihf` to build for ARMv6, and add architecture for crosstool-ng-based images.
- #709 - Update Emscripten targets to `emcc` version 3.1.10
Expand Down
20 changes: 18 additions & 2 deletions src/docker.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus};
use std::{env, fs};

use crate::cargo::Root;
use crate::errors::*;
use crate::extensions::{CommandExt, SafeCommand};
use crate::file::write_file;
use crate::id;
use crate::{Config, Target};
use atty::Stream;
Expand All @@ -14,6 +16,11 @@ const DOCKER_IMAGES: &[&str] = &include!(concat!(env!("OUT_DIR"), "/docker-image
const CROSS_IMAGE: &str = "ghcr.io/cross-rs";
const DOCKER: &str = "docker";
const PODMAN: &str = "podman";
// secured profile based off the docker documentation for denied syscalls:
// https://docs.docker.com/engine/security/seccomp/#significant-syscalls-blocked-by-the-default-profile
// note that we've allow listed `clone` and `clone3`, which is necessary
// to fork the process, and which podman allows by default.
const SECCOMP: &str = include_str!("seccomp.json");

fn get_container_engine() -> Result<std::path::PathBuf, which::Error> {
if let Ok(ce) = env::var("CROSS_CONTAINER_ENGINE") {
Expand Down Expand Up @@ -170,8 +177,17 @@ pub fn run(

docker.arg("--rm");

if target.needs_docker_privileged() {
docker.arg("--privileged");
// docker uses seccomp now on all installations
if target.needs_docker_seccomp() {
let path = env::current_dir()
.wrap_err("couldn't get current directory")?
.join("target")
.join(target.triple())
.join("seccomp.json");
if !path.exists() {
write_file(&path, false)?.write_all(SECCOMP.as_bytes())?;
}
docker.args(&["--security-opt", &format!("seccomp={}", path.display())]);
}

// We need to specify the user for Docker, but not for Podman.
Expand Down
18 changes: 17 additions & 1 deletion src/file.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::fs::File;
use std::fs::{self, File};
use std::io::Read;
use std::path::Path;

Expand All @@ -19,3 +19,19 @@ fn read_(path: &Path) -> Result<String> {
.wrap_err_with(|| format!("couldn't read {}", path.display()))?;
Ok(s)
}

pub fn write_file(path: impl AsRef<Path>, overwrite: bool) -> Result<File> {
let path = path.as_ref();
fs::create_dir_all(&path.parent().ok_or_else(|| {
eyre::eyre!(format!(
"could not find parent directory for `{}`",
path.display()
))
})?)
.wrap_err_with(|| format!("couldn't create directory `{}`", path.display()))?;
fs::OpenOptions::new()
.write(true)
.create_new(!overwrite)
.open(&path)
.wrap_err(format!("could't write to file `{}`", path.display()))
}
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ impl Target {
!native && (self.is_linux() || self.is_windows() || self.is_bare_metal())
}

fn needs_docker_privileged(&self) -> bool {
fn needs_docker_seccomp(&self) -> bool {
let arch_32bit = self.triple().starts_with("arm")
|| self.triple().starts_with("i586")
|| self.triple().starts_with("i686");
Expand Down
157 changes: 157 additions & 0 deletions src/seccomp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
{
"defaultAction": "SCMP_ACT_ALLOW",
"defaultErrnoRet": 1,
"syscalls": [
{
"names": [
"add_key",
"get_kernel_syms",
"keyctl",
"move_pages",
"nfsservctl",
"perf_event_open",
"pivot_root",
"query_module",
"request_key",
"sysfs",
"_sysctl",
"uselib",
"userfaultfd",
"ustat"
],
"action": "SCMP_ACT_ERRNO"
},
{
"names": [
"acct"
],
"action": "SCMP_ACT_ERRNO",
"excludes": {
"caps": [
"CAP_SYS_PACCT"
]
}
},
{
"names": [
"bpf",
"lookup_dcookie",
"mount",
"quotactl",
"quotactl_fd",
"setns",
"swapon",
"swapoff",
"umount",
"umount2",
"unshare",
"vm86",
"vm86old",
"pciconfig_read",
"pciconfig_write",
"salinfo_log_open",
"salinfo_event_open",
"sys_cacheflush",
"rtas"
],
"action": "SCMP_ACT_ERRNO",
"excludes": {
"caps": [
"CAP_SYS_ADMIN"
]
}
},
{
"names": [
"clock_adjtime",
"clock_settime",
"settimeofday",
"stime"
],
"action": "SCMP_ACT_ERRNO",
"excludes": {
"caps": [
"CAP_SYS_TIME"
]
}
},
{
"names": [
"create_module",
"delete_module",
"finit_module",
"init_module"
],
"action": "SCMP_ACT_ERRNO",
"excludes": {
"caps": [
"CAP_SYS_MODULE"
]
}
},
{
"names": [
"get_mempolicy",
"mbind",
"set_mempolicy"
],
"action": "SCMP_ACT_ERRNO",
"excludes": {
"caps": [
"CAP_SYS_NICE"
]
}
},
{
"names": [
"ioperm",
"iopl"
],
"action": "SCMP_ACT_ERRNO",
"excludes": {
"caps": [
"CAP_SYS_RAWIO"
]
}
},
{
"names": [
"kcmp",
"process_vm_readv",
"process_vm_writev",
"ptrace"
],
"action": "SCMP_ACT_ERRNO",
"excludes": {
"caps": [
"CAP_SYS_PTRACE"
]
}
},
{
"names": [
"kexec_file_load",
"kexec_load",
"reboot"
],
"action": "SCMP_ACT_ERRNO",
"excludes": {
"caps": [
"CAP_SYS_BOOT"
]
}
},
{
"names": [
"name_to_handle_at",
"open_by_handle_at"
],
"action": "SCMP_ACT_ERRNO",
"excludes": {
"caps": [
"CAP_DAC_READ_SEARCH"
]
}
}
]
}

0 comments on commit 4888d06

Please sign in to comment.