NAME
pledge —
restrict system operations
SYNOPSIS
#include
<unistd.h>
int
pledge(const
char *promises, const
char *execpromises);
DESCRIPTION
The
pledge()
system call seperates the POSIX featureset into a group of approximately 3
dozen subsystems. By calling pledge() the program
can declare which subsystems it will need in the future in a space-seperated
string called promises. Subsystems not listed become
unavailable, and most attempts to use operations in that subsystem result in
the process being killed with an uncatchable
SIGABRT, delivering a core file if possible.
Subsequent calls to
pledge()
can reduce the subsystems which still work, but previously revoked
subsystems cannot be re-activated.
Passing NULL to
promises or execpromises
specifies to not change the current value.
A few changes to POSIX behaviour come into effect on
the first call to
pledge(),
regardless of the promise arguments:
- adjtime(2):
- Time cannot be changed. Only the olddelta argument works.
- chmod(2), fchmod(2), fchmodat(2), chown(2), lchown(2), fchown(2), fchownat(2), mkfifo(2), and mknod(2):
- Setuid/setgid/sticky bits are ignored. User or group cannot be changed.
The
fattrpromise relaxes this behaviour slightly. - ioctl(2):
- Only the
FIONREAD,FIONBIO,FIOCLEX, andFIONCLEXoperations are allowed by default. All other ioctl operations are blocked, except for ones which are enabled by specfic promises:audio,bpf,disklabel,drm,inet,pf,route,wroute,tape,tty,video, andvmm. - mmap(2) and mprotect(2):
PROT_EXECis not allowed, unless theprot_execpromise is requested.- __pledge_open(2):
- A few system files can be opened directly by
libcinternal code using this hidden symbol system call when specific promises are requested, but applications cannot open those files themselves. This works even whenrpathorwpathare absent and unveil(2) cannot block opening the files. These are the promises which can read special files: promises. pledge():- Can only reduce permissions for promises and execpromises.
- sysctl(2):
- A small set of read-only operations are allowed, sufficient to support: getdomainname(3), gethostname(3), getifaddrs(3), uname(3), and system sensor readings. Some promises expose more read-only operations.
The promises argument is specified as a string, with space separated keywords. Using "" restricts the process to the _exit(2) system call (this can be used for pure computation operating on memory shared with another process).
stdio- This promise provides access to basic memory
management, actions upon already open file descriptors, inspection of
various process attributes, timer resources, and other subsystems
generally considered safe because they only occur inside the process..
Many of these interfaces are then used inside higher-level libc
functionality, which is why the name
stdiowas chosen. The following system calls are permitted:clock_getres(2), clock_gettime(2), close(2), closefrom(2), dup(2), dup2(2), dup3(2), fchdir(2), fcntl(2), fstat(2), fsync(2), ftruncate(2), getdtablecount(2), getegid(2), getentropy(2), geteuid(2), getgid(2), getgroups(2), getitimer(2), getlogin(2), getpgid(2), getpgrp(2), getpid(2), getppid(2), getresgid(2), getresuid(2), getrlimit(2), getrtable(2), getsid(2), getthrid(2), gettimeofday(2), getuid(2), issetugid(2), kevent(2), kqueue(2), kqueue1(2), lseek(2), madvise(2), minherit(2), mmap(2), mprotect(2), mquery(2), munmap(2), nanosleep(2), pipe(2), pipe2(2), poll(2), pread(2), preadv(2), profil(2), pwrite(2), pwritev(2), read(2), readv(2), recvfrom(2), recvmsg(2), select(2), sendmsg(2), sendsyslog(2), sendto(2), setitimer(2), shutdown(2), sigaction(2), sigprocmask(2), sigreturn(2), socketpair(2), umask(2), wait4(2), waitid(2), write(2), writev(2)
sendto(2) is only permitted if the destination socket address is
NULL. rpath- A number of system calls are allowed which allow path traversal, reading struct stat, and opening files for read.
wpath- Similar to
rpath, but files can be opened for write. cpath- Similar to
wpath, but files can also be created or removed. dpath- Similar to
cpath, but special files can be created using: tmppath- No longer available. This pledge was designed to satisfy the
mkstemp(3) family of functions. The limited filesystem access it
provided is now disabled, so the promise has been removed and will return
EINVAL. It should be replaced by either allowing use of the whole filesystem, meaning "rpath wpath cpath", or use of unveil(2) with path "/tmp" and permissions "rwc". inet- The following system calls are allowed to operate in the
AF_INETandAF_INET6domains (though setsockopt(2) has been substantially reduced in functionality):socket(2), listen(2), bind(2), connect(2), accept4(2), accept(2), getpeername(2), getsockname(2), setsockopt(2), getsockopt(2)
mcast- In combination with
inetgive back functionality to setsockopt(2) for operating on multicast sockets. fattr- The following system calls are allowed to make explicit changes to fields
in struct stat relating to a file:
utimes(2), futimes(2), utimensat(2), futimens(2), chmod(2), fchmod(2), fchmodat(2), chflags(2), chflagsat(2), chown(2), fchownat(2), lchown(2), fchown(2), utimes(2)
chown- The chown(2) family is allowed to change the user or group on a file.
flock- File locking via fcntl(2), flock(2), lockf(3), and open(2) is allowed. No distinction is made between shared and exclusive locks. This promise is required for unlock as well as lock.
unix- The following system calls are allowed to operate in the
AF_UNIXdomain:socket(2), listen(2), bind(2), connect(2), accept4(2), accept(2), getpeername(2), getsockname(2), setsockopt(2), getsockopt(2)
The bind(2) call can create AF_UNIX sockets at any path even without
wpath,and connect(2) can connect at any path even withoutrpathorwpath. dns- Some low-level behaviours required by the DNS resolver described in
res_init(3) are permitted. THis includes
__pledge_open(2) reading
hosts(5),
protocols(5),
resolv.conf(5), and
services(5), and exposing a few networking system calls:
socket(2), connect(2),
sendto(2), recvfrom(2) which can only operate on the specific socket
type
SOCK_DNS. The library resolver opens sockets withSOCK_DNSonly on port 53, so the kernel can differentiate these operations from regular sockets operations. getpw- This uses the special features of __pledge_open(2) to read required system files to support the getpwnam(3), getgrnam(3), getgrouplist(3), and initgroups(3) family of functions, including lookups via the yp(8) protocol for YP and LDAP databases.
sendfd- Allows sending of file descriptors using sendmsg(2). File descriptors referring to directories may not be passed.
recvfd- Allows receiving of file descriptors using recvmsg(2). File descriptors referring to directories may not be passed.
tape- Allow
MTIOCGETandMTIOCTOPoperations against tape drives. tty- In addition to allowing read-write operations on
/dev/tty, this opens up a variety of
ioctl(2)
requests used by tty devices. If
ttyis accompanied withrpath, revoke(2) is permitted. Otherwise only the following ioctl(2) requests are permitted:TIOCSPGRP,TIOCGETA,TIOCGPGRP,TIOCGWINSZ,TIOCSWINSZ,TIOCSBRK,TIOCCDTR,TIOCSETA,TIOCSETAW,TIOCSETAF,TIOCUCNTL proc- Allows the following process relationship operations:
fork(2), vfork(2), kill(2), getpriority(2), setpriority(2), setrlimit(2), setpgid(2), setsid(2)
exec- Allows a process to call
execve(2). Coupled with the
procpromise, this allows a process to fork and execute another program. If execpromises has been previously set the new program begins with those promises, unless setuid/setgid bits are set in which case execution is blocked withEACCES. Otherwise the new program starts running without pledge active, and hopefully makes a new pledge soon. prot_exec- Allows the use of
PROT_EXECwith mmap(2) and mprotect(2). settime- Allows the setting of system time, via the settimeofday(2), adjtime(2), and adjfreq(2) system calls.
ps- Allows enough sysctl(2) interfaces to allow inspection of processes operating on the system using programs like ps(1).
vminfo- Allows enough sysctl(2) interfaces to allow inspection of the system's virtual memory by programs like top(1) and vmstat(8).
id- Allows the following system calls which can change the rights of a
process:
setuid(2), seteuid(2), setreuid(2), setresuid(2), setgid(2), setegid(2), setregid(2), setresgid(2), setgroups(2), setlogin(2), setrlimit(2), getpriority(2), setpriority(2), setrtable(2)
pf- Allows a subset of ioctl(2) operations on the
pf(4) device:
DIOCADDRULE,DIOCGETSTATUS,DIOCNATLOOK,DIOCRADDTABLES,DIOCRCLRADDRS,DIOCRCLRTABLES,DIOCRCLRTSTATS,DIOCRGETTSTATS,DIOCRSETADDRS,DIOCXBEGIN,DIOCXCOMMIT route- Allow inspection of the routing table.
wroute- Allow changes to the routing table.
audio- Allows a subset of ioctl(2) operations on
audio(4)
devices (see sio_open(3) for more information):
AUDIO_GETPOS,AUDIO_GETPAR,AUDIO_SETPAR,AUDIO_START,AUDIO_STOP,AUDIO_MIXER_DEVINFO,AUDIO_MIXER_READ,AUDIO_MIXER_WRITE video- Allows a subset of ioctl(2) operations on
video(4)
devices:
VIDIOC_DQBUF,VIDIOC_ENUM_FMT,VIDIOC_ENUM_FRAMEINTERVALS,VIDIOC_ENUM_FRAMESIZES,VIDIOC_G_CTRL,VIDIOC_G_PARM,VIDIOC_QBUF,VIDIOC_QUERYBUF,VIDIOC_QUERYCAP,VIDIOC_QUERYCTRL,VIDIOC_S_CTRL,VIDIOC_S_FMT,VIDIOC_S_PARM,VIDIOC_STREAMOFF,VIDIOC_STREAMON,VIDIOC_TRY_FMT,VIDIOC_REQBUFS bpf- Allow
BIOCGSTATSoperation for statistics collection from a bpf(4) device. unveil- Allow unveil(2) to be called.
error- Rather than killing the process upon violation, indicate error with
ENOSYS.Also when
pledge() is called with higher promises or execpromises, those changes will be ignored and return success. This is useful when a parent enforces execpromises but an execve'd child has a different idea.
A process currently running with pledge has state ‘p’ in ps(1) output; a process that was terminated due to a pledge violation is accounted by lastcomm(1) with the ‘P’ flag.
RETURN VALUES
Upon successful completion, the value 0 is returned; otherwise the value -1 is returned and the global variable errno is set to indicate the error.
ERRORS
pledge() will fail if:
- [
EFAULT] - promises or execpromises points outside the process's allocated address space.
- [
EINVAL] - promises is malformed or contains invalid keywords.
- [
EPERM] - This process is attempting to increase permissions.
HISTORY
The pledge() system call first appeared in
OpenBSD 5.9.