policy-maker
is a language and CLI for defining Seccomp BPF rules in a higher level way. You provide a Seccomp BPF policy definition under the .pol
format and the CLI generates a plug-and-play code that installs a Seccomp BPF filter in your application.
This project was a undergraduate thesis project at Aeronautics Institute of Technology (ITA) in Brazil. The original thesis (in Portuguese) can be found here.
This project is heavilly inspired by Kafel, a C library that aims to provide a higher level interface for defining Seccomp BPF rules. If you are looking for a C library, you should check it out.
The main difference between policy-maker
and Kafel is that policy-maker
is a CLI, while Kafel
is a C library. This means that policy-maker
aims to be easier to use and integrate with projects, but it also can be less flexible.
policy-maker
is distributed as a single executable file. You can download the latest version from the releases page.
Alternatively, you can build it from source. You'll need to have g++
, make
, python3
, flex
and bison
installed. Once you have all these dependencies installed, you can build policy-maker by running:
make
This will build policy-maker inside the bin
directory with the name compiler
.
Either way, you can place the executable file anywhere in your system and rename it to whatever you want, but it's recommended to keep the name policy-maker
and place it under a directory that is in your PATH
environment variable (usually /usr/bin/
).
First, define a policy under the .pol
format. You can find some examples under the samples
directory. For example, the following policy will allow all syscalls except socket
, which will terminate the process:
// main.pol
policy main allow or {
terminate {
socket,
}
}
Then, run the CLI:
policy-maker ./main.pol
The CLI will generate a C file called filter.c
and a header file called filter.h
. You can then compile and link them with your application. These files expose a single function called install_filter
that installs the Seccomp BPF filter in your application. You can call this function at any time, but it is recommended to call it as soon as possible in your application.
All those names are customizable via CLI Options. For example, you can have a compiled output file named custom_name.c
with a function named custom_name
by running:
policy-maker ./main.pol --output custom_name.c --target custom_name
Alternatively, you can run a command with the specified policy applied without having to compile and link the generated files. All you need to do is pass the command arguments after all the policy-maker arguments.
For example, the following command will run ls
with the policy defined in main.pol
applied:
policy-maker ./main.pol ls
Under interactive mode, if you defined any syscall under a notify
action, a worker process will be spawned to log all the syscalls that were notified and allow them.
Under the hood, the spawned process uses pidfd_open
and pidfd_getfd
to retrieve the notif file descriptor from the sandboxed process. This means that the worker process will only work if the kernel supports these syscalls.
Important: The interactive mode depends on execve
being allowed. If you wish to use the interactive mode, make sure to allow execve
in your policy.
There's no documentation for the policy language yet. You can check out the samples under the samples
directory to get an idea of how it works or get the original thesis (in Portuguese) here.
Usage: policy-maker <input>
[--target (-t) <target>]
[--print-analyzed-ast]
[--print-ast]
[--dry-run (-d)]
[--output (-o) <output>]
[--entry (-e) <entry>]
[--print-bpf]
[--help (-h)]
[...]
Parameters:
input ( --input, -i ): The input file to compile
--target, -t: Name of the generated function
--print-analyzed-ast: Print the analyzed AST to stdout
--print-ast: Print the AST to stdout
--dry-run, -d: Don't produce any output. Just validates the input file
--output, -o: The output file to write to
--entry, -e: The entry point of the program
--print-bpf: Print the final BPF code to stdout
--help, -h: Print this help message and exit
[...] If present, any arguments after the compiler options will be passed to execvp after the filter is installed. No output will be generated.
I don't have any defined contribution guidelines yet. If you want to contribute, feel free to open an issue or a pull request.
This project is licensed under the MIT License - see the LICENSE file for details.