diff --git a/capsicum.go b/capsicum.go new file mode 100644 index 0000000..f3d4826 --- /dev/null +++ b/capsicum.go @@ -0,0 +1,242 @@ +// This is an implementation of libbsm +// Copyright johan@nosd.in 2023 +// +//go:build freebsd +// +build freebsd + +// + +package main + + +const ( + // From freeebsd-src/sys/sys/caprights.h : + /* + * The top two bits in the first element of the cr_rights[] array contain + * total number of elements in the array - 2. This means if those two bits are + * equal to 0, we have 2 array elements. + * The top two bits in all remaining array elements should be 0. + * The next five bits contain array index. Only one bit is used and bit position + * in this five-bits range defines array index. This means there can be at most + * five array elements. + */ + // So, I lazily chose to include index bit in following values + /* INDEX 0 */ + + /* + * General file I/O. + */ + /* Allows for openat(O_RDONLY), read(2), readv(2). */ + CAP_READ = 0x0200000000000001 + /* Allows for openat(O_WRONLY | O_APPEND), write(2), writev(2). */ + CAP_WRITE = 0x0200000000000002 + /* Allows for lseek(fd, 0, SEEK_CUR). */ + CAP_SEEK_TELL = 0x0200000000000004 + /* Allows for lseek(2). */ + CAP_SEEK = CAP_SEEK_TELL | 0x0200000000000008 + /* Allows for aio_read(2), pread(2), preadv(2). */ + CAP_PREAD = (CAP_SEEK | CAP_READ) + /* + * Allows for aio_write(2), openat(O_WRONLY) (without O_APPEND), pwrite(2), + * pwritev(2). + */ + CAP_PWRITE = (CAP_SEEK | CAP_WRITE) + /* Allows for mmap(PROT_NONE). */ + CAP_MMAP = 0x0200000000000010 + /* Allows for mmap(PROT_READ). */ + CAP_MMAP_R = (CAP_MMAP | CAP_SEEK | CAP_READ) + /* Allows for mmap(PROT_WRITE). */ + CAP_MMAP_W = (CAP_MMAP | CAP_SEEK | CAP_WRITE) + /* Allows for mmap(PROT_EXEC). */ + CAP_MMAP_X = (CAP_MMAP | CAP_SEEK | 0x0200000000000020) + /* Allows for mmap(PROT_READ | PROT_WRITE). */ + CAP_MMAP_RW = (CAP_MMAP_R | CAP_MMAP_W) + /* Allows for mmap(PROT_READ | PROT_EXEC). */ + CAP_MMAP_RX = (CAP_MMAP_R | CAP_MMAP_X) + /* Allows for mmap(PROT_WRITE | PROT_EXEC). */ + CAP_MMAP_WX = (CAP_MMAP_W | CAP_MMAP_X) + /* Allows for mmap(PROT_READ | PROT_WRITE | PROT_EXEC). */ + CAP_MMAP_RWX = (CAP_MMAP_R | CAP_MMAP_W | CAP_MMAP_X) + /* Allows for openat(O_CREAT). */ + CAP_CREATE = 0x0200000000000040 + /* Allows for openat(O_EXEC) and fexecve(2) in turn. */ + CAP_FEXECVE = 0x0200000000000080 + /* Allows for openat(O_SYNC), openat(O_FSYNC), fsync(2), aio_fsync(2). */ + CAP_FSYNC = 0x0200000000000100 + /* Allows for openat(O_TRUNC), ftruncate(2). */ + CAP_FTRUNCATE = 0x0200000000000200 + + /* Lookups - used to constrain *at() calls. */ + CAP_LOOKUP = 0x0200000000000400 + + /* VFS methods. */ + /* Allows for fchdir(2). */ + CAP_FCHDIR = 0x0200000000000800 + /* Allows for fchflags(2). */ + CAP_FCHFLAGS = 0x0200000000001000 + /* Allows for fchflags(2) and chflagsat(2). */ + CAP_CHFLAGSAT = (CAP_FCHFLAGS | CAP_LOOKUP) + /* Allows for fchmod(2). */ + CAP_FCHMOD = 0x0200000000002000 + /* Allows for fchmod(2) and fchmodat(2). */ + CAP_FCHMODAT = (CAP_FCHMOD | CAP_LOOKUP) + /* Allows for fchown(2). */ + CAP_FCHOWN = 0x0200000000004000 + /* Allows for fchown(2) and fchownat(2). */ + CAP_FCHOWNAT = (CAP_FCHOWN | CAP_LOOKUP) + /* Allows for fcntl(2). */ + CAP_FCNTL = 0x0200000000008000 + /* + * Allows for flock(2), openat(O_SHLOCK), openat(O_EXLOCK), + * fcntl(F_SETLK_REMOTE), fcntl(F_SETLKW), fcntl(F_SETLK), fcntl(F_GETLK). + */ + CAP_FLOCK = 0x0200000000010000 + /* Allows for fpathconf(2). */ + CAP_FPATHCONF = 0x0200000000020000 + /* Allows for UFS background-fsck operations. */ + CAP_FSCK = 0x0200000000040000 + /* Allows for fstat(2). */ + CAP_FSTAT = 0x0200000000080000 + /* Allows for fstat(2), fstatat(2) and faccessat(2). */ + CAP_FSTATAT = (CAP_FSTAT | CAP_LOOKUP) + /* Allows for fstatfs(2). */ + CAP_FSTATFS = 0x0200000000100000 + /* Allows for futimens(2) and futimes(2). */ + CAP_FUTIMES = 0x0200000000200000 + /* Allows for futimens(2), futimes(2), futimesat(2) and utimensat(2). */ + CAP_FUTIMESAT = (CAP_FUTIMES | CAP_LOOKUP) + /* Allows for linkat(2) (target directory descriptor). */ + CAP_LINKAT_TARGET = (CAP_LOOKUP | 0x0200000000400000) + /* Allows for mkdirat(2). */ + CAP_MKDIRAT = (CAP_LOOKUP | 0x0200000000800000) + /* Allows for mkfifoat(2). */ + CAP_MKFIFOAT = (CAP_LOOKUP | 0x0200000001000000) + /* Allows for mknodat(2). */ + CAP_MKNODAT = (CAP_LOOKUP | 0x0200000002000000) + /* Allows for renameat(2) (source directory descriptor). */ + CAP_RENAMEAT_SOURCE = (CAP_LOOKUP | 0x0200000004000000) + /* Allows for symlinkat(2). */ + CAP_SYMLINKAT = (CAP_LOOKUP | 0x0200000008000000) + /* + * Allows for unlinkat(2) and renameat(2) if destination object exists and + * will be removed. + */ + CAP_UNLINKAT = (CAP_LOOKUP | 0x0200000010000000) + + /* Socket operations. */ + /* Allows for accept(2) and accept4(2). */ + CAP_ACCEPT = 0x0200000020000000 + /* Allows for bind(2). */ + CAP_BIND = 0x0200000040000000 + /* Allows for connect(2). */ + CAP_CONNECT = 0x0200000080000000 + /* Allows for getpeername(2). */ + CAP_GETPEERNAME = 0x0200000100000000 + /* Allows for getsockname(2). */ + CAP_GETSOCKNAME = 0x0200000200000000 + /* Allows for getsockopt(2). */ + CAP_GETSOCKOPT = 0x0200000400000000 + /* Allows for listen(2). */ + CAP_LISTEN = 0x0200000800000000 + /* Allows for sctp_peeloff(2). */ + CAP_PEELOFF = 0x0300001000000000 + CAP_RECV = CAP_READ + CAP_SEND = CAP_WRITE + /* Allows for setsockopt(2). */ + CAP_SETSOCKOPT = 0x0200002000000000 + /* Allows for shutdown(2). */ + CAP_SHUTDOWN = 0x0200004000000000 + + /* Allows for bindat(2) on a directory descriptor. */ + CAP_BINDAT = (CAP_LOOKUP | 0x0200008000000000) + /* Allows for connectat(2) on a directory descriptor. */ + CAP_CONNECTAT = (CAP_LOOKUP | 0x0200010000000000) + + /* Allows for linkat(2) (source directory descriptor). */ + CAP_LINKAT_SOURCE = (CAP_LOOKUP | 0x0200020000000000) + /* Allows for renameat(2) (target directory descriptor). */ + CAP_RENAMEAT_TARGET = (CAP_LOOKUP | 0x0200040000000000) + + CAP_SOCK_CLIENT = (CAP_CONNECT | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT | + CAP_PEELOFF | CAP_RECV | CAP_SEND | CAP_SETSOCKOPT | CAP_SHUTDOWN) + CAP_SOCK_SERVER = (CAP_ACCEPT | CAP_BIND | CAP_GETPEERNAME | CAP_GETSOCKNAME | + CAP_GETSOCKOPT | CAP_LISTEN | CAP_PEELOFF | CAP_RECV | CAP_SEND | + CAP_SETSOCKOPT | CAP_SHUTDOWN) + + /* All used bits for index 0. */ + CAP_ALL0 = 0x020007FFFFFFFFFF + + /* Available bits for index 0. */ + CAP_UNUSED0_44 = 0x0200080000000000 + /* ... */ + CAP_UNUSED0_57 = 0x0300000000000000 + + /* INDEX 1 */ + + /* Mandatory Access Control. */ + /* Allows for mac_get_fd(3). */ + CAP_MAC_GET = 0x0400000000000001 + /* Allows for mac_set_fd(3). */ + CAP_MAC_SET = 0x0400000000000002 + + /* Methods on semaphores. */ + CAP_SEM_GETVALUE = 0x0400000000000004 + CAP_SEM_POST = 0x0400000000000008 + CAP_SEM_WAIT = 0x0400000000000010 + + /* Allows select(2) and poll(2) on descriptor. */ + CAP_EVENT = 0x0400000000000020 + /* Allows for kevent(2) on kqueue descriptor with eventlist != NULL. */ + CAP_KQUEUE_EVENT = 0x0400000000000040 + + /* Strange and powerful rights that should not be given lightly. */ + /* Allows for ioctl(2). */ + CAP_IOCTL = 0x0400000000000080 + CAP_TTYHOOK = 0x0400000000000100 + + /* Process management via process descriptors. */ + /* Allows for pdgetpid(2). */ + CAP_PDGETPID = 0x0400000000000200 + /* + * Allows for pdwait4(2). + * + * XXX: this constant was imported unused, but is targeted to be implemented + * in the future (bug 235871). + */ + CAP_PDWAIT = 0x0400000000000400 + /* Allows for pdkill(2). */ + CAP_PDKILL = 0x0400000000000800 + + /* Extended attributes. */ + /* Allows for extattr_delete_fd(2). */ + CAP_EXTATTR_DELETE = 0x0400000000001000 + /* Allows for extattr_get_fd(2). */ + CAP_EXTATTR_GET = 0x0400000000002000 + /* Allows for extattr_list_fd(2). */ + CAP_EXTATTR_LIST = 0x0400000000004000 + /* Allows for extattr_set_fd(2). */ + CAP_EXTATTR_SET = 0x0400000000008000 + + /* Access Control Lists. */ + /* Allows for acl_valid_fd_np(3). */ + CAP_ACL_CHECK = 0x0400000000010000 + /* Allows for acl_delete_fd_np(3). */ + CAP_ACL_DELETE = 0x0400000000020000 + /* Allows for acl_get_fd(3) and acl_get_fd_np(3). */ + CAP_ACL_GET = 0x0400000000040000 + /* Allows for acl_set_fd(3) and acl_set_fd_np(3). */ + CAP_ACL_SET = 0x0400000000080000 + + /* Allows for kevent(2) on kqueue descriptor with changelist != NULL. */ + CAP_KQUEUE_CHANGE = 0x0400000000100000 + + CAP_KQUEUE = (CAP_KQUEUE_EVENT | CAP_KQUEUE_CHANGE) + + /* All used bits for index 1. */ + CAP_ALL1 = 0x04000000001FFFFF + + /* Available bits for index 1. */ + CAP_UNUSED1_22 = 0x0400000000200000 + /* ... */ + CAP_UNUSED1_57 = 0x0500000000000000 +)