Skip to content

Commit

Permalink
No cap sys ptrace (#17)
Browse files Browse the repository at this point in the history
* Make it work without CAP_SYS_PTRACE whenever possible.
  • Loading branch information
igankevich authored May 1, 2024
1 parent 806c30f commit a6d7575
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 131 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
ci:
runs-on: ubuntu-latest
container:
image: ghcr.io/staex-io/cijail-ci:latest@sha256:a34338b49056f528fbf439f0dc6c196c01b38174aa7ad9345b1bb8c00c8dea52
image: ghcr.io/staex-io/cijail-ci:latest@sha256:592e78d4432c1db857cd0e64d6a4c89b5d056358291a5e81b73fd8ee907a14de
credentials:
username: token
password: ${{ secrets.GHCR_TOKEN }}
Expand All @@ -19,7 +19,8 @@ jobs:
lb-140-82-113-3-iad.github.com:443 lb-140-82-114-4-iad.github.com:443 lb-140-82-116-4-sea.github.com:443
151.101.44.223:443 lb-140-82-113-4-iad.github.com:443 api.github.com:443 uploads.github.com:443
lb-140-82-116-14-sea.github.com:443 lb-140-82-112-13-iad.github.com:443 lb-140-82-114-3-iad.github.com:443
lb-140-82-116-3-sea.github.com:443 lb-140-82-112-3-iad.github.com:443
lb-140-82-116-3-sea.github.com:443 lb-140-82-112-3-iad.github.com:443 151.101.130.137:443
151.101.2.137:443 151.101.66.137:443 151.101.194.137:443
steps:
- name: Checkout
uses: actions/[email protected]
Expand Down
14 changes: 7 additions & 7 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cijail"
version = "0.4.2"
version = "0.5.0"
edition = "2021"
publish = false

Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ Cijail makes it impossible to exfiltrate the data over DNS and makes it difficul
(The future versions will include HTTPS URL filter as well that would give even more granular control.)

Cijail is implemented using [`seccomp`](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
needs [`CAP_SYS_PTRACE`](https://man7.org/linux/man-pages/man7/capabilities.7.html) capability to read memory of the processes being traced.
sometimes needs [`CAP_SYS_PTRACE`](https://man7.org/linux/man-pages/man7/capabilities.7.html) capability to read memory of the processes being traced.
Our local Docker installation does not require this privilege,
whereas Github Actions runners require.
The capability is dropped before the command is executed.


# Usage
Expand Down Expand Up @@ -93,7 +96,7 @@ variables:
✅ Gitlab CI/CD pipelines respect Docker's `ENTRYPOINT`,
and you do not have to prepend `cijail` to every command.

Then you need to add `CAP_SYS_PTRACE` capability to your Gitlab runner configuration.
Then you *might* need to add `CAP_SYS_PTRACE` capability to your Gitlab runner configuration.
Currently this is supported only for the runners that you host yourself.
To do that add the following lines to `/etc/gitlab-runner/config.toml`.

Expand Down
2 changes: 1 addition & 1 deletion ci/binaries.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh

set -ex
if test "$GITHUB_REF_TYPE" != "tag"; then
if test "$GITHUB_ACTIONS" = "true" && test "$GITHUB_REF_TYPE" != "tag"; then
exit 0
fi
rust_flags="-Ccodegen-units=1 -Cstrip=symbols -Copt-level=3 -Cincremental=false -Clto=yes -Cembed-bitcode=yes"
Expand Down
2 changes: 1 addition & 1 deletion ci/release.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh
set -ex
if test "$GITHUB_REF_TYPE" != "tag"; then
if test "$GITHUB_ACTIONS" = "true" && test "$GITHUB_REF_TYPE" != "tag"; then
exit 0
fi
curl -sL \
Expand Down
23 changes: 23 additions & 0 deletions src/bin/print-caps/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::process::ExitCode;

use caps::errors::CapsError;
use caps::CapSet;

fn main() -> Result<ExitCode, CapsError> {
for set in [
CapSet::Permitted,
CapSet::Effective,
CapSet::Inheritable,
CapSet::Ambient,
CapSet::Bounding,
] {
let capabilities = caps::read(None, set)?;
let mut capabilities = capabilities
.iter()
.map(|x| x.to_string())
.collect::<Vec<_>>();
capabilities.sort();
println!("{:?}: {}", set, capabilities.join(" "));
}
Ok(ExitCode::SUCCESS)
}
12 changes: 10 additions & 2 deletions src/bin/test-caps/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
use std::process::ExitCode;

use caps::errors::CapsError;
use caps::CapSet;
use caps::Capability;
use std::process::ExitCode;

fn main() -> Result<ExitCode, CapsError> {
// bounding set
if caps::has_cap(None, CapSet::Effective, Capability::CAP_SETPCAP)?
&& caps::has_cap(None, CapSet::Bounding, Capability::CAP_SYS_PTRACE)?
{
return Ok(ExitCode::FAILURE);
}
// other sets
for set in [
CapSet::Bounding,
CapSet::Permitted,
CapSet::Effective,
CapSet::Inheritable,
CapSet::Ambient,
Expand Down
19 changes: 8 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,17 @@ fn install_seccomp_notify_filter() -> Result<ScmpFd, Error> {
}

fn drop_capabilities() -> Result<(), CapsError> {
const CAP: Capability = Capability::CAP_SYS_PTRACE;
if caps::has_cap(None, CapSet::Effective, Capability::CAP_SETPCAP)?
&& caps::has_cap(None, CapSet::Bounding, Capability::CAP_SYS_PTRACE)?
&& caps::has_cap(None, CapSet::Bounding, CAP)?
{
info!(
"dropping CAP_SYS_PTRACE from the {:?} set",
CapSet::Bounding
);
caps::drop(None, CapSet::Bounding, Capability::CAP_SYS_PTRACE)?;
info!("dropping `{}` from the `{:?}` set", CAP, CapSet::Bounding);
caps::drop(None, CapSet::Bounding, CAP)?;
}
for set in [CapSet::Effective, CapSet::Inheritable, CapSet::Ambient] {
if caps::has_cap(None, set, Capability::CAP_SYS_PTRACE)? {
info!("dropping CAP_SYS_PTRACE from the {:?} set", set);
caps::drop(None, set, Capability::CAP_SYS_PTRACE)?;
}
let set = CapSet::Ambient;
if caps::has_cap(None, set, CAP)? {
info!("dropping `{}` from the `{:?}` set", CAP, set);
caps::drop(None, set, CAP)?;
}
Ok(())
}
Expand Down
Loading

0 comments on commit a6d7575

Please sign in to comment.