July 4, 2025
This article explores how OpenBSD and Linux use self-imposed sandboxes to enhance security, focusing on the tools `pledge()` and `seccomp()`. We'll dive into how each system implements these sandboxes and the differences between them.
What is `pledge()` in OpenBSD?
`pledge()` is a system call that looks like a sandbox but a big difference between `pledge()` and classic sandboxes is sandboxes control program accessibility to system resources by kernel. But `pledge()` is different. `pledge()` voluntarily limits its own access. For example, the echo command (UNIX system tool) doesn't require access to files or sockets. Doesn’t need I/O in file or socket access. Echo only needs stdio (standard input/output) so it promises to use only it and if echo uses any other resource kernel kills the program with SIGABRT (signal abort). This system call was introduced in OpenBSD 5.9 (March 2016). `pledge()` is a core part of layered security in OpenBSD’s system design.
What is the difference between `pledge()` in OpenBSD and `seccomp()` in Linux?
First of all, we need to explain what `seccomp()` is. `seccomp()` is similar to `pledge()` but is used in Linux. It is a self-imposed sandbox, similar to `pledge()`. However, a major difference between the two is that `pledge()` is developer-friendly (easy to use for programmers) whereas `seccomp()` is more precise, you can set arguments for system calls. For example, when you add stdio to the allow system calls you can set only allows write operation on stdout.
in pledge:
#include <unistd.h>
pledge("stdio", NULL);
let me talk later about Null parameter
in seccomp:
#include <seccomp.h>
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
seccomp_load(ctx);
seccomp_release(ctx);
Another important difference between the two is that in `seccomp()` you can define or modify policies dynamically at runtime while in `pledge()`, policies can only be set once.
in conclusion, `pledge()` is well-suited for used in simple programs or minimal tools and `seccomp()` used for advanced programs.
pledge function signature:
int pledge(const char *promises, const char *execpromises);
promises → the list of promises the program makes, such as "stdio" or "rpath"
execpromises → the restrictions that apply to the program it calls exec()
, i.e., if this program executes another program, what permissions it will have.
A small UNIX tool that uses pledge()
and seccomp()
for curious minds.
Check it out on GitHub:
shellStone - echo implementation.
See also: pledge(2), seccomp(2)