Skip to content

Fix travis #1123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions test/sys/test_ptrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::mem;
fn test_ptrace() {
// Just make sure ptrace can be called at all, for now.
// FIXME: qemu-user doesn't implement ptrace on all arches, so permit ENOSYS
require_capability!(CAP_SYS_PTRACE);
let err = ptrace::attach(getpid()).unwrap_err();
assert!(err == Error::Sys(Errno::EPERM) || err == Error::Sys(Errno::EINVAL) ||
err == Error::Sys(Errno::ENOSYS));
Expand All @@ -21,6 +22,7 @@ fn test_ptrace() {
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptrace_setoptions() {
require_capability!(CAP_SYS_PTRACE);
let err = ptrace::setoptions(getpid(), Options::PTRACE_O_TRACESYSGOOD).unwrap_err();
assert!(err != Error::UnsupportedOperation);
}
Expand All @@ -29,6 +31,7 @@ fn test_ptrace_setoptions() {
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptrace_getevent() {
require_capability!(CAP_SYS_PTRACE);
let err = ptrace::getevent(getpid()).unwrap_err();
assert!(err != Error::UnsupportedOperation);
}
Expand All @@ -37,6 +40,7 @@ fn test_ptrace_getevent() {
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptrace_getsiginfo() {
require_capability!(CAP_SYS_PTRACE);
if let Err(Error::UnsupportedOperation) = ptrace::getsiginfo(getpid()) {
panic!("ptrace_getsiginfo returns Error::UnsupportedOperation!");
}
Expand All @@ -46,6 +50,7 @@ fn test_ptrace_getsiginfo() {
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptrace_setsiginfo() {
require_capability!(CAP_SYS_PTRACE);
let siginfo = unsafe { mem::zeroed() };
if let Err(Error::UnsupportedOperation) = ptrace::setsiginfo(getpid(), &siginfo) {
panic!("ptrace_setsiginfo returns Error::UnsupportedOperation!");
Expand All @@ -61,6 +66,8 @@ fn test_ptrace_cont() {
use nix::unistd::fork;
use nix::unistd::ForkResult::*;

require_capability!(CAP_SYS_PTRACE);

let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");

// FIXME: qemu-user doesn't implement ptrace on all architectures
Expand Down
8 changes: 8 additions & 0 deletions test/sys/test_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ pub fn test_af_alg_cipher() {
ControlMessage, MsgFlags};
use nix::sys::socket::sockopt::AlgSetKey;

// Travis's seccomp profile blocks AF_ALG
// https://docs.docker.com/engine/security/seccomp/
skip_if_seccomp!(test_af_alg_cipher);

let alg_type = "skcipher";
let alg_name = "ctr(aes)";
// 256-bits secret key
Expand Down Expand Up @@ -308,6 +312,10 @@ pub fn test_af_alg_aead() {
ControlMessage, MsgFlags};
use nix::sys::socket::sockopt::{AlgSetKey, AlgSetAeadAuthSize};

// Travis's seccomp profile blocks AF_ALG
// https://docs.docker.com/engine/security/seccomp/
skip_if_seccomp!(test_af_alg_aead);

let auth_size = 4usize;
let assoc_size = 16u32;

Expand Down
1 change: 1 addition & 0 deletions test/sys/test_uio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ fn test_process_vm_readv() {
use nix::sys::signal::*;
use nix::sys::wait::*;

require_capability!(CAP_SYS_PTRACE);
let _ = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");

// Pre-allocate memory in the child, since allocation isn't safe
Expand Down
1 change: 1 addition & 0 deletions test/sys/test_wait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ mod ptrace {

#[test]
fn test_wait_ptrace() {
require_capability!(CAP_SYS_PTRACE);
let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");

match fork().expect("Error: Fork Failed") {
Expand Down
61 changes: 50 additions & 11 deletions test/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,28 @@ extern crate rand;
extern crate sysctl;
extern crate tempfile;

#[cfg(any(target_os = "android", target_os = "linux"))]
macro_rules! require_capability {
($capname:ident) => {
use ::caps::{Capability, CapSet, has_cap};
use ::std::io::{self, Write};
cfg_if! {
if #[cfg(any(target_os = "android", target_os = "linux"))] {
macro_rules! require_capability {
($capname:ident) => {
use ::caps::{Capability, CapSet, has_cap};
use ::std::io::{self, Write};

if !has_cap(None, CapSet::Effective, Capability::$capname).unwrap() {
let stderr = io::stderr();
let mut handle = stderr.lock();
writeln!(handle, "Insufficient capabilities. Skipping test.")
.unwrap();
return;
if !has_cap(None, CapSet::Effective, Capability::$capname)
.unwrap()
{
let stderr = io::stderr();
let mut handle = stderr.lock();
writeln!(handle,
"Insufficient capabilities. Skipping test.")
.unwrap();
return;
}
}
}
} else {
macro_rules! require_capability {
($capname:ident) => {}
}
}
}
Expand Down Expand Up @@ -63,6 +73,35 @@ macro_rules! skip_if_not_root {
};
}

cfg_if! {
if #[cfg(any(target_os = "android", target_os = "linux"))] {
macro_rules! skip_if_seccomp {
($name:expr) => {
if let Ok(s) = std::fs::read_to_string("/proc/self/status") {
for l in s.lines() {
let mut fields = l.split_whitespace();
if fields.next() == Some("Seccomp:") &&
fields.next() != Some("0")
{
use ::std::io::Write;
let stderr = ::std::io::stderr();
let mut handle = stderr.lock();
writeln!(handle,
"{} cannot be run in Seccomp mode. Skipping test.",
stringify!($name)).unwrap();
return;
}
}
}
}
}
} else {
macro_rules! skip_if_seccomp {
($name:expr) => {}
}
}
}

mod sys;
mod test_dir;
mod test_fcntl;
Expand Down
25 changes: 17 additions & 8 deletions test/test_unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,13 @@ macro_rules! execve_test_factory(
($test_name:ident, $syscall:ident, $exe: expr $(, $pathname:expr, $flags:expr)*) => (
#[test]
fn $test_name() {
let _m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
if "execveat" == stringify!($syscall) {
// Though undocumented, Docker's default seccomp profile seems to
// block this syscall. https://github.com/nix-rust/nix/issues/1122
skip_if_seccomp!($test_name);
}

let m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");
// The `exec`d process will write to `writer`, and we'll read that
// data from `reader`.
let (reader, writer) = pipe().unwrap();
Expand All @@ -194,12 +200,9 @@ macro_rules! execve_test_factory(
// The tests make sure not to do that, though.
match fork().unwrap() {
Child => {
// Close stdout.
close(1).unwrap();
// Make `writer` be the stdout of the new process.
dup(writer).unwrap();
// exec!
$syscall(
dup2(writer, 1).unwrap();
let r = $syscall(
$exe,
$(&CString::new($pathname).unwrap(), )*
&[CString::new(b"".as_ref()).unwrap(),
Expand All @@ -208,11 +211,17 @@ macro_rules! execve_test_factory(
.as_ref()).unwrap()],
&[CString::new(b"foo=bar".as_ref()).unwrap(),
CString::new(b"baz=quux".as_ref()).unwrap()]
$(, $flags)*).unwrap();
$(, $flags)*);
let _ = std::io::stderr()
.write_all(format!("{:?}", r).as_bytes());
// Should only get here in event of error
unsafe{ _exit(1) };
},
Parent { child } => {
// Wait for the child to exit.
waitpid(child, None).unwrap();
let ws = waitpid(child, None);
drop(m);
assert_eq!(ws, Ok(WaitStatus::Exited(child, 0)));
// Read 1024 bytes.
let mut buf = [0u8; 1024];
read(reader, &mut buf).unwrap();
Expand Down