Skip to content
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

Update seccompiler to use libseccomp #4926

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

ShadowCurse
Copy link
Contributor

@ShadowCurse ShadowCurse commented Nov 25, 2024

Changes

Replace our custom implementation of a seccompiler with libseccomp.
By out test, libseccomp produces ~65% smaller binaries which is very beneficial as we embed the combination of those into the Firecracker.

In order to interact with libseccomp we add custom bindings which contain only the needed set of methods, constants needed for our use case. This simplifies the maintenance and avoids adding dependencies.

Reason

libseccomp provides better quality compiler for BPF seccomp programs than our current implementation.

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license. For more information on following Developer
Certificate of Origin and signing off your commits, please check
CONTRIBUTING.md.

PR Checklist

  • I have read and understand CONTRIBUTING.md.
  • I have run tools/devtool checkstyle to verify that the PR passes the
    automated style checks.
  • I have described what is done in these changes, why they are needed, and
    how they are solving the problem in a clear and encompassing way.
  • I have updated any relevant documentation (both in code and in the docs)
    in the PR.
  • I have mentioned all user-facing changes in CHANGELOG.md.
  • If a specific issue led to this PR, this PR closes the issue.
  • When making API changes, I have followed the
    Runbook for Firecracker API changes.
  • I have tested all new and changed functionalities in unit tests and/or
    integration tests.
  • I have linked an issue to every new TODO.

  • This functionality cannot be added in rust-vmm.

@ShadowCurse ShadowCurse force-pushed the seccomp2 branch 13 times, most recently from 6bdce02 to b44d926 Compare November 28, 2024 10:24
Copy link

codecov bot commented Nov 28, 2024

Codecov Report

Attention: Patch coverage is 22.55639% with 206 lines in your changes missing coverage. Please review.

Project coverage is 83.07%. Comparing base (89ca781) to head (42787fa).

Current head 42787fa differs from pull request most recent head 96c905e

Please upload reports for the commit 96c905e to get more accurate results.

Files with missing lines Patch % Lines
src/seccompiler/src/lib.rs 0.00% 92 Missing ⚠️
src/seccompiler/src/types.rs 0.00% 87 Missing ⚠️
src/seccompiler/src/bin.rs 0.00% 13 Missing ⚠️
src/vmm/src/seccomp.rs 89.06% 7 Missing ⚠️
src/seccompiler/src/bindings.rs 0.00% 6 Missing ⚠️
src/vmm/src/builder.rs 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4926      +/-   ##
==========================================
- Coverage   83.93%   83.07%   -0.86%     
==========================================
  Files         248      247       -1     
  Lines       27791    26684    -1107     
==========================================
- Hits        23326    22169    -1157     
- Misses       4465     4515      +50     
Flag Coverage Δ
5.10-c5n.metal 83.58% <22.55%> (-0.94%) ⬇️
5.10-m5n.metal 83.57% <22.55%> (-0.93%) ⬇️
5.10-m6a.metal 82.77% <22.55%> (-1.01%) ⬇️
5.10-m6g.metal 79.46% <22.55%> (-1.16%) ⬇️
5.10-m6i.metal 83.56% <22.55%> (-0.93%) ⬇️
5.10-m7g.metal 79.46% <22.55%> (-1.16%) ⬇️
6.1-c5n.metal 83.58% <22.55%> (?)
6.1-m5n.metal 83.57% <22.55%> (?)
6.1-m6a.metal 82.77% <22.55%> (?)
6.1-m6g.metal 79.46% <22.55%> (?)
6.1-m6i.metal 83.55% <22.55%> (?)
6.1-m7g.metal 79.46% <22.55%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ShadowCurse ShadowCurse self-assigned this Nov 28, 2024
@ShadowCurse ShadowCurse force-pushed the seccomp2 branch 5 times, most recently from 3fb90d6 to 4ef05b8 Compare November 28, 2024 13:40
Cargo.toml Outdated Show resolved Hide resolved
@ShadowCurse ShadowCurse force-pushed the seccomp2 branch 2 times, most recently from 50ac4e6 to 919390b Compare November 28, 2024 14:12
@alindima
Copy link
Contributor

libseccomp provides better quality compiler for
bpf seccomp programs than our current implementation.

I'm curious, what does this mean? and how was this evaluated?

@ShadowCurse ShadowCurse force-pushed the seccomp2 branch 5 times, most recently from 775c84f to 1b253fb Compare November 29, 2024 14:04
@ShadowCurse ShadowCurse added the Type: Enhancement Indicates new feature requests label Dec 11, 2024
@pb8o
Copy link
Contributor

pb8o commented Dec 11, 2024

libseccomp provides better quality compiler for bpf seccomp programs than our current implementation.

I'm curious, what does this mean? and how was this evaluated?

Hi @alindima! We found this while revisiting seccomp recently:

  • libseccomp produces shorter cBPF programs, around ~65% fewer instructions. The difference is small and probably jitted away, but the bytecode is much easier to read and audit.
  • libseccomp has a few interesting features implemented like syscall prioritization. While we don't use this presently, we have had situations where we would like control the order of the syscall rules. For example we can put the most called syscalls first.
  • Finally libseccomp is installed by default in many distros and is a dependency of systemd for example, so we assume it is well-maintained and robust. By doing that we can reduce our maintenance effort and focus more on Firecracker.

src/vmm/src/seccomp.rs Show resolved Hide resolved
tools/devctr/Dockerfile Show resolved Hide resolved
src/seccompiler/Cargo.toml Outdated Show resolved Hide resolved
@@ -0,0 +1,169 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were those generated by bindgen? If no, why wasn't that feasible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are some mix of https://github.com/libseccomp-rs/libseccomp-rs/blob/main/libseccomp-sys/src/lib.rs and new rust syntax (the unsafe extern and safe keyword). I did not auto generate them.

src/seccompiler/src/types.rs Outdated Show resolved Hide resolved
@pb8o pb8o self-requested a review December 11, 2024 18:29
Copy link
Contributor

@pb8o pb8o left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should fix the ioctl syscall id getting resolved at build time instead of at runtime.

@ShadowCurse ShadowCurse force-pushed the seccomp2 branch 2 times, most recently from 1fc051b to c411a78 Compare December 11, 2024 22:02
src/seccompiler/src/types.rs Outdated Show resolved Hide resolved
pb8o
pb8o previously approved these changes Dec 12, 2024
@pb8o pb8o self-requested a review December 12, 2024 10:32
@pb8o pb8o force-pushed the seccomp2 branch 3 times, most recently from 0e3f083 to 93cc0a2 Compare December 16, 2024 16:32
roypat
roypat previously approved these changes Dec 16, 2024
@pb8o pb8o force-pushed the seccomp2 branch 3 times, most recently from 7b1ef1c to 42787fa Compare December 16, 2024 17:01
ShadowCurse and others added 8 commits December 17, 2024 10:39
libseccomp provides a better quality compiler for
BPF seccomp programs than our current implementation. In our testing
it produces BPF code with ~65% less instructions which makes final
binaries smaller which in turn makes Firecracker binary smaller because
we include them into Firecracker at build time.

For this transition we create a minimal set of bindings for `libseccomp`
in order to simplify maintenance and avoid adding additional
dependencies.

The only tricky issue with this transition is the way `ioctl` and other
syscalls are checked with libseccomp. It always adds a check for the
high bits of the request to be 0. Unfortunately when we build with
`musl`, some syscalls like `ioctl` have upper bits set to 1. Because of
this, we replace `Eq` with `MaskedEq` with mask `0x00000000FFFFFFFF`
when the argument is 32bits.

This commit also removes dependency of firecracker and vmm
crates on the seccompiler crate.

Co-authored-by: Pablo Barbáchano <pablob@amazon.com>
Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
Since we depend on libseccomp in the previous commit, these commands to
update the syscall table are no longer needed.

Signed-off-by: Pablo Barbáchano <pablob@amazon.com>
According to
https://www.man7.org/linux/man-pages/man2/PR_SET_SECCOMP.2const.html
using `prctl` for setting seccomp filer is deprecated, so switch to
using `syscall` instead.

Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
Replace __errno_location() with std::io::Error::last_os_error() as a
more standard of getting errno value.

Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
The error enum had only 1 element and we can replace it with
alias for simplicity.

Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
Add a note about updating backend for seccompiler
to libseccomp.

Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
We need to compile it from source because version provided by the
distribution is not compiled with musl-gcc.

Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
Kani on x86 for some reason cannot find libseccomp by default,
so we add additional path to the build.rs

Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
@roypat
Copy link
Contributor

roypat commented Dec 17, 2024

(just resolved merge conflict so there's a chance my approval will survive me going on vacation)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting review Indicates that a pull request is ready to be reviewed Type: Enhancement Indicates new feature requests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants