Skip to content

Commit

Permalink
Merge #745 #746
Browse files Browse the repository at this point in the history
745: Add `thumbv7neon-*` targets. r=otavio a=Alexhuszagh

Add the `thumbv7neon-linux-androideabi` and `thumbv7neon-unknown-linux-gnueabihf` targets.
    
Closes #254.

746: Limit permissions for Android images. r=otavio,emilgardis a=Alexhuszagh

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.

Co-authored-by: Alex Huszagh <ahuszagh@gmail.com>
  • Loading branch information
bors[bot] and Alexhuszagh authored Jun 8, 2022
3 parents cf38147 + 2d2b5d3 + 13f4497 commit 3a061f8
Show file tree
Hide file tree
Showing 8 changed files with 341 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ jobs:
- { target: arm-unknown-linux-gnueabihf, os: ubuntu-latest, cpp: 1, dylib: 1, std: 1, run: 1 }
- { target: armv7-unknown-linux-gnueabi, os: ubuntu-latest, cpp: 1, dylib: 1, std: 1, run: 1, runners: qemu-user qemu-system }
- { target: armv7-unknown-linux-gnueabihf, os: ubuntu-latest, cpp: 1, dylib: 1, std: 1, run: 1, runners: qemu-user qemu-system }
- { target: thumbv7neon-unknown-linux-gnueabihf, os: ubuntu-latest, cpp: 1, dylib: 1, std: 1, run: 1, runners: qemu-user qemu-system }
- { target: i586-unknown-linux-gnu, os: ubuntu-latest, cpp: 1, dylib: 1, std: 1, run: 1 }
- { target: i686-unknown-linux-gnu, os: ubuntu-latest, cpp: 1, dylib: 1, std: 1, run: 1, runners: native qemu-user qemu-system }
- { target: mips-unknown-linux-gnu, os: ubuntu-latest, cpp: 1, dylib: 1, std: 1, run: 1, runners: qemu-user qemu-system }
Expand Down Expand Up @@ -167,6 +168,7 @@ jobs:
- { target: aarch64-linux-android, os: ubuntu-latest, cpp: 1, std: 1, run: 1, runners: qemu-user }
- { target: arm-linux-androideabi, os: ubuntu-latest, cpp: 1, std: 1, run: 1, runners: qemu-user }
- { target: armv7-linux-androideabi, os: ubuntu-latest, cpp: 1, std: 1, run: 1, runners: qemu-user }
- { target: thumbv7neon-linux-androideabi, os: ubuntu-latest, cpp: 1, std: 1, run: 1, runners: qemu-user }
- { target: i686-linux-android, os: ubuntu-latest, cpp: 1, std: 1, run: 1, runners: qemu-user }
- { target: x86_64-linux-android, os: ubuntu-latest, cpp: 1, std: 1, run: 1, runners: qemu-user }
- { target: x86_64-pc-windows-gnu, os: ubuntu-latest, cpp: 1, std: 1, run: 1 }
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added

- #767 - added the `cross-util` and `cross-dev` commands.
- #745 - added `thumbv7neon-*` targets.
- #741 - added `armv7-unknown-linux-gnueabi` and `armv7-unknown-linux-musleabi` targets.
- #721 - add support for running doctests on nightly if `CROSS_UNSTABLE_ENABLE_DOCTESTS=true`.
- #719 - add `--list` to known subcommands.
Expand All @@ -23,6 +24,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- #762 - re-enabled `x86_64-unknown-dragonfly` target.
- #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
55 changes: 55 additions & 0 deletions docker/Dockerfile.thumbv7neon-linux-androideabi
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive

COPY common.sh lib.sh /
RUN /common.sh

COPY cmake.sh /
RUN /cmake.sh

COPY xargo.sh /
RUN /xargo.sh

COPY android-ndk.sh /
RUN /android-ndk.sh arm 28
ENV PATH=$PATH:/android-ndk/bin

COPY android-system.sh /
RUN /android-system.sh arm

COPY qemu.sh /
RUN /qemu.sh arm

RUN cp /android-ndk/sysroot/usr/lib/arm-linux-androideabi/28/libz.so /system/lib/

COPY android-runner /

# Libz is distributed in the android ndk, but for some unknown reason it is not
# found in the build process of some crates, so we explicit set the DEP_Z_ROOT
# likewise, the toolchains expect the prefix `thumbv7neon-linux-androideabi`,
# which we don't have, so just export every possible variable, such as AR.
# Also export all target binutils just in case required.
ENV CARGO_TARGET_THUMBV7NEON_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \
CARGO_TARGET_THUMBV7NEON_LINUX_ANDROIDEABI_RUNNER="/android-runner arm" \
AR_thumbv7neon_linux_androideabi=arm-linux-androideabi-ar \
AS_thumbv7neon_linux_androideabi=arm-linux-androideabi-as \
CC_thumbv7neon_linux_androideabi=arm-linux-androideabi-gcc \
CXX_thumbv7neon_linux_androideabi=arm-linux-androideabi-g++ \
LD_thumbv7neon_linux_androideabi=arm-linux-androideabi-ld \
NM_thumbv7neon_linux_androideabi=arm-linux-androideabi-nm \
OBJCOPY_thumbv7neon_linux_androideabi=arm-linux-androideabi-objcopy \
OBJDUMP_thumbv7neon_linux_androideabi=arm-linux-androideabi-objdump \
RANLIB_thumbv7neon_linux_androideabi=arm-linux-androideabi-ranlib \
READELF_thumbv7neon_linux_androideabi=arm-linux-androideabi-readelf \
SIZE_thumbv7neon_linux_androideabi=arm-linux-androideabi-size \
STRINGS_thumbv7neon_linux_androideabi=arm-linux-androideabi-strings \
STRIP_thumbv7neon_linux_androideabi=arm-linux-androideabi-strip \
BINDGEN_EXTRA_CLANG_ARGS_thumbv7neon_linux_androideabi="--sysroot=/android-ndk/sysroot" \
DEP_Z_INCLUDE=/android-ndk/sysroot/usr/include/ \
RUST_TEST_THREADS=1 \
HOME=/tmp/ \
TMPDIR=/tmp/ \
ANDROID_DATA=/ \
ANDROID_DNS_MODE=local \
ANDROID_ROOT=/system

47 changes: 47 additions & 0 deletions docker/Dockerfile.thumbv7neon-unknown-linux-gnueabihf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
FROM ubuntu:16.04
ARG DEBIAN_FRONTEND=noninteractive

COPY common.sh lib.sh /
RUN /common.sh

COPY cmake.sh /
RUN /cmake.sh

COPY xargo.sh /
RUN /xargo.sh

RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
g++-arm-linux-gnueabihf \
libc6-dev-armhf-cross

COPY qemu.sh /
RUN /qemu.sh arm softmmu

COPY dropbear.sh /
RUN /dropbear.sh

COPY linux-image.sh /
RUN /linux-image.sh armv7

COPY linux-runner /

# Export all target binutils just in case required.
ENV CARGO_TARGET_THUMBV7NEON_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \
CARGO_TARGET_THUMBV7NEON_UNKNOWN_LINUX_GNUEABIHF_RUNNER="/linux-runner armv7" \
AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \
AS_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-as \
CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \
LD_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ld \
NM_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-nm \
OBJCOPY_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-objcopy \
OBJDUMP_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-objdump \
RANLIB_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ranlib \
READELF_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-readelf \
SIZE_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-size \
STRINGS_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-strings \
STRIP_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-strip \
BINDGEN_EXTRA_CLANG_ARGS_thumbv7neon_unknown_linux_gnueabihf="--sysroot=/usr/arm-linux-gnueabihf" \
QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf \
RUST_TEST_THREADS=1 \
PKG_CONFIG_PATH="/usr/lib/arm-linux-gnueabihf/pkgconfig/:${PKG_CONFIG_PATH}"
57 changes: 51 additions & 6 deletions src/docker.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus};
use std::{env, fs};

use crate::cargo::CargoMetadata;
use crate::extensions::{CommandExt, SafeCommand};
use crate::file::write_file;
use crate::id;
use crate::{errors::*, file};
use crate::{Config, Target};
Expand All @@ -14,16 +16,34 @@ 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");

#[derive(Debug, PartialEq, Eq)]
enum EngineType {
Docker,
Podman,
Other,
}

// determine if the container engine is docker. this fixes issues with
// any aliases (#530), and doesn't fail if an executable suffix exists.
fn get_is_docker(ce: std::path::PathBuf, verbose: bool) -> Result<bool> {
fn get_engine_type(ce: std::path::PathBuf, verbose: bool) -> Result<EngineType> {
let stdout = Command::new(ce)
.arg("--help")
.run_and_get_stdout(verbose)?
.to_lowercase();

Ok(stdout.contains("docker") && !stdout.contains("emulate"))
if stdout.contains("podman") {
Ok(EngineType::Podman)
} else if stdout.contains("docker") && !stdout.contains("emulate") {
Ok(EngineType::Docker)
} else {
Ok(EngineType::Other)
}
}

pub fn get_container_engine() -> Result<std::path::PathBuf, which::Error> {
Expand Down Expand Up @@ -172,7 +192,7 @@ pub fn run(
let runner = config.runner(target)?;

let mut docker = docker_command("run")?;
let is_docker = get_is_docker(get_container_engine().unwrap(), verbose)?;
let engine_type = get_engine_type(get_container_engine().unwrap(), verbose)?;

for ref var in config.env_passthrough(target)? {
validate_env_var(var)?;
Expand Down Expand Up @@ -233,12 +253,37 @@ 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 seccomp = if engine_type == EngineType::Docker && cfg!(target_os = "windows") {
// docker on windows fails due to a bug in reading the profile
// https://github.com/docker/for-win/issues/12760
"unconfined".to_string()
} else {
#[allow(unused_mut)] // target_os = "windows"
let mut path = env::current_dir()
.wrap_err("couldn't get current directory")?
.canonicalize()
.wrap_err_with(|| "when canonicalizing current_dir".to_string())?
.join("target")
.join(target.triple())
.join("seccomp.json");
if !path.exists() {
write_file(&path, false)?.write_all(SECCOMP.as_bytes())?;
}
#[cfg(target_os = "windows")]
if engine_type == EngineType::Podman {
// podman weirdly expects a WSL path here, and fails otherwise
path = wslpath(&path, verbose)?;
}
path.display().to_string()
};

docker.args(&["--security-opt", &format!("seccomp={}", seccomp)]);
}

// We need to specify the user for Docker, but not for Podman.
if is_docker {
if engine_type == EngineType::Docker {
docker.args(&[
"--user",
&format!(
Expand Down
17 changes: 16 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, PathBuf};

Expand Down Expand Up @@ -35,3 +35,18 @@ fn _canonicalize(path: &Path) -> Result<PathBuf> {
Path::new(&path).canonicalize().map_err(Into::into)
}
}

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!("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()))
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,9 @@ 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("thumb")
|| self.triple().starts_with("i586")
|| self.triple().starts_with("i686");

Expand Down
Loading

0 comments on commit 3a061f8

Please sign in to comment.