pledge —
restrict system operations
#include
<unistd.h>
int
pledge(
const
char *promises,
const char
*execpromises);
The
pledge system call forces the current process
into a restricted-service operating mode. A few subsets are available, roughly
described as computation, memory management, read-write operations on file
descriptors, opening of files, and networking. In general, these modes were
selected by studying the operation of many programs using libc and other such
interfaces, and setting
promises or
execpromises.
Use of
pledge in an application will require at
least some study and understanding of the interfaces called. Subsequent calls
to
pledge can reduce the abilities further, but
abilities can never be regained.
A process which attempts a restricted operation is killed with an uncatchable
SIGABRT
, delivering a core file if
possible. 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.
A
promises value of "" restricts the
process to the
_exit(2) system
call. This can be used for pure computation operating on memory shared with
another process.
Passing
NULL
to
promises or
execpromises specifies to not change the
current value.
Some system calls, when allowed, have restrictions applied to them:
- access(2):
- May check for existence of
/etc/localtime.
- adjtime(2):
- Read-only, for
ntpd(8).
- 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. The user or group
cannot be changed on a file.
- ioctl(2):
- Only the
FIONREAD
,
FIONBIO
,
FIOCLEX
, and
FIONCLEX
operations are allowed by
default. Various ioctl requests are allowed against specific file
descriptors based upon the requests
audio,
bpf,
disklabel,
drm,
inet,
pf,
route,
tape,
tty, and
vmm.
- mmap(2) and
mprotect(2):
PROT_EXEC
isn't allowed.
- open(2):
- May open /etc/localtime and
any files below /usr/share/zoneinfo.
- pledge:
- Can only reduce permissions for
promises and
execpromises.
- readlink(2):
- May operate on
/etc/malloc.conf.
- 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.
The
promises argument is specified as a string,
with space separated keywords:
-
-
- stdio
- The following system calls are permitted.
sendto(2) is only permitted
if its destination socket address is
NULL
. As a result, all the expected
functionalities of libc stdio work.
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),
getdents(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),
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),
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),
write(2),
writev(2)
-
-
- rpath
- A number of system calls are allowed if they only cause
read-only effects on the filesystem:
chdir(2),
getcwd(3),
openat(2),
fstatat(2),
faccessat(2),
readlinkat(2),
lstat(2),
chmod(2),
fchmod(2),
fchmodat(2),
chflags(2),
chflagsat(2),
chown(2),
fchown(2),
fchownat(2),
fstat(2),
getfsstat(2)
-
-
- wpath
- A number of system calls are allowed and may cause
write-effects on the filesystem:
getcwd(3),
openat(2),
fstatat(2),
faccessat(2),
readlinkat(2),
lstat(2),
chmod(2),
fchmod(2),
fchmodat(2),
chflags(2),
chflagsat(2),
chown(2),
fchown(2),
fchownat(2),
fstat(2)
-
-
- cpath
- A number of system calls and sub-modes are allowed, which
may create new files or directories in the filesystem:
rename(2),
renameat(2),
link(2),
linkat(2),
symlink(2),
symlinkat(2),
unlink(2),
unlinkat(2),
mkdir(2),
mkdirat(2),
rmdir(2)
-
-
- dpath
- A number of system calls are allowed to create special
files:
mkfifo(2),
mknod(2)
-
-
- tmppath
- A number of system calls are allowed to do operations in
the /tmp directory, including create, read,
or write:
lstat(2),
chmod(2),
chflags(2),
chown(2),
unlink(2),
fstat(2)
-
-
- inet
- The following system calls are allowed to operate in the
AF_INET
and
AF_INET6
domains (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 inet
give 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_UNIX
domain:
socket(2),
listen(2),
bind(2),
connect(2),
accept4(2),
accept(2),
getpeername(2),
getsockname(2),
setsockopt(2),
getsockopt(2)
-
-
- dns
- Subsequent to a successful
open(2) of
/etc/resolv.conf, a few system calls become
able to allow DNS network transactions:
sendto(2),
recvfrom(2),
socket(2),
connect(2)
-
-
- getpw
- This allows read-only opening of files in
/etc for the
getpwnam(3),
getgrnam(3),
getgrouplist(3), and
initgroups(3) family of
functions. They may also need to operate in a
yp(8) environment, so a
successful open(2) of
/var/run/ypbind.lock enables
inet operations.
-
-
- 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
MTIOCGET
and
MTIOCTOP
operations 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 tty is accompanied with
rpath,
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
proc promise, 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 with
EACCESS
. Otherwise the new program
starts running without pledge active, and hopefully makes a new pledge
soon.
-
-
- prot_exec
- Allows the use of
PROT_EXEC
with
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)
-
-
- pf
- Allows a subset of
ioctl(2) operations on the
pf(4) device:
DIOCADDRULE
,
DIOCGETSTATUS
,
DIOCNATLOOK
,
DIOCRADDTABLES
,
DIOCRCLRADDRS
,
DIOCRCLRTABLES
,
DIOCRCLRTSTATS
,
DIOCRGETTSTATS
,
DIOCRSETADDRS
,
DIOCXBEGIN
,
DIOCXCOMMIT
-
-
- 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
-
-
- bpf
- Allow
BIOCGSTATS
operation for statistics collection from a
bpf(4) device.
-
-
- 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.
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.
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.
The
pledge system call first appeared in
OpenBSD 5.9.