Skip to content

A language and CLI for defining Seccomp BPF rules in a higher level way

License

Notifications You must be signed in to change notification settings

dfidalg0/policy-maker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Policy Maker

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.

Similar Projects

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.

Instalation

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/).

Usage

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.

Policy Language 🚧

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.

CLI Options

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.

Contributing

I don't have any defined contribution guidelines yet. If you want to contribute, feel free to open an issue or a pull request.

License

This project is licensed under the MIT License - see the LICENSE file for details.