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

Add Seccomp bits for linux #10717

Merged
merged 3 commits into from
Apr 28, 2022
Merged

Add Seccomp bits for linux #10717

merged 3 commits into from
Apr 28, 2022

Conversation

The-King-of-Toasters
Copy link
Contributor

@The-King-of-Toasters The-King-of-Toasters commented Jan 29, 2022

Full functionality necessitates a classic BPF implementation, so I did that too. Included is a simulator for debugging/testing purposes. It's been fuzzed for a couple days and I haven't found any errors. It may be worth de-duplicating the shared constants in std.os.linux.BPF and std.x.net.bpf later on.

Most of the effort was spent writing the documentation for the bpf/seccomp bits, so I hope that everything is clear and understandable.

There's a small issue relating to @offsetOf that I'll open a new issue for: #10718.

This library contains:
- The global constants as used by C code.
- An Insn struct that implements can generate all the BPF instructions.
- A simple BPF virtual machine implementation that can be used for
  testing programs. This has complete code-coverage and has been
  extensively fuzzed.
Also adds the _CSKY and _FRV ELF machines that are defined in
`<linux/elf-em.h>`
Copy link
Contributor

@matu3ba matu3ba left a comment

Choose a reason for hiding this comment

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

just a nit on comments. otherwise looking good, though I did not test this yet.
do you have a plan how and when to test this in CI to track upstream Kernel?

Side question: Are there other OSes with bpf support? Otherwise bpf.zig belongs into os/linux.

lib/std/os/linux/seccomp.zig Outdated Show resolved Hide resolved
lib/std/os/linux/seccomp.zig Outdated Show resolved Hide resolved
@The-King-of-Toasters
Copy link
Contributor Author

BPF is supported on many different OSs and all implementations - besides Linux - share code. This is the problem with OS testing. For example, here's how to attach a filter to an interface on OpenBSD:

  • Open /dev/bpf O_RDONLY.
  • Issue a bunch of ioctls to the device, including BIOCSETIF.
  • Set the filter using the BIOCSETF ioctl command. The filter is contained in a bpf_program struct:
    struct bpf_program {
        u_int bf_len;
        struct bpf_insn *bf_insns;
    };
  • Loop reading the bpf device to get new bpf_hdr structs.

On Linux, the process is:

  • Create an AF_PACKET socket.
  • Bind the socket to the interface using a sockaddr_ll struct.
  • Set the filter using the SO_ATTACH_FILTER setsockopt option. The filter is contained in a sock_fprog struct:
    struct sock_fprog {
        unsigned short     len;
        struct sock_filter *filter;
    };
  • Loop recving the socket to get packets.

On top of the OS-level differences, network packet capturing requires root privilege on the *BSDs and the CAP_NET_RAW capability on Linux.

Note, this is from a surface-level reading of tcpdump/libpcap. There are most likely errors.

Seccomp testing shouldn't be too hard, I left it out because it requires a bit of work:

  • Create a pipe/socketpair.
  • fork/clone to create a new process.
  • Set a seccomp filter in the child process that returns an errno for invalid syscalls.
  • Test for passing/failing syscalls and write the errno on the pipe.
  • The parent reads the errnos and asserts they're the correct values.
  • The parent kills the child.

@The-King-of-Toasters
Copy link
Contributor Author

I've tweaked and added to the seccomp documentation.

@The-King-of-Toasters
Copy link
Contributor Author

I've just touched up the docs one last time. @matu3ba, do you require any changes or is it good to merge as is?

@matu3ba
Copy link
Contributor

matu3ba commented Feb 13, 2022

I like the tests and the documentation is very nice to read. Since sockets are untested on Unixes, this should be good to merge.

lib/std/os/linux/seccomp.zig Outdated Show resolved Hide resolved
@matu3ba
Copy link
Contributor

matu3ba commented Mar 8, 2022

@The-King-of-Toasters I was wrong on sockets on Linux (in x/os/net.zig). You can find a simple child process with pipe example for a temporary generated program here: https://gist.github.com/matu3ba/0add09568327bad64e7181f9faadca40

  1. However, the paths are wrong, if I use a test block instead of main function.
  2. The pipe test is in os/test.zig under test "pipe" and needs to be included into my example.
  3. It would be nice, if build.zig would have functionality for that as to not rely on hacky path workarounds.

@The-King-of-Toasters
Copy link
Contributor Author

I'm open to writing proper tests, however I feel writing a new style of test is out of scope for this addition, and should be worked on in its own PR.

I've also removed the few remaining references to args[n], so I think everything is in place.

@Vexu Vexu merged commit 6d48600 into ziglang:master Apr 28, 2022
Copy link
Member

@andrewrk andrewrk left a comment

Choose a reason for hiding this comment

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

Thanks for the patch. I found a couple issues, but nothing so problematic as to deserve a revert.

const _64BIT = 0x80000000;
const _LE = 0x40000000;

pub const current = switch (native_arch) {
Copy link
Member

Choose a reason for hiding this comment

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

missing type annotation (should have type ARCH)

.powerpc => .PPC,
.powerpc64 => .PPC64,
.powerpc64le => .PPC64LE,
else => undefined,
Copy link
Member

Choose a reason for hiding this comment

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

should be else => @compileError("unsupported architecture")

@The-King-of-Toasters
Copy link
Contributor Author

Thanks for the feedback, will follow up with a commit soon.

andrewrk pushed a commit that referenced this pull request Apr 29, 2022
- Add type annotation for AUDIT.current.
- Make unsupported archs a compile error.
kubkon pushed a commit that referenced this pull request May 2, 2022
- Add type annotation for AUDIT.current.
- Make unsupported archs a compile error.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants