CAP_FILEARGS(3)
π
CAP_FILEARGS(3) β your bestie's guide to the cap_fileargs library (Library Functions Manual) π¦
okay so first things first, this is cap_fileargs(3) from the Library Functions Manual, and it's genuinely one of those pages that looks scary but is actually just "here's how to open files after you've locked yourself in the Capsicum sandbox." no cap. let's get into it π
β¨ NAME β¨
cap_fileargs, fileargs_cinit, fileargs_cinitnv, fileargs_init, fileargs_initnv, fileargs_free, fileargs_lstat, fileargs_open, fileargs_fopen β literally the whole library for handling files in capability mode π
πΈ SYNOPSIS πΈ
library βlibcap_fileargsβ #include <sys/nv.h>
#include <libcasper.h>
#include <casper/cap_fileargs.h>
fileargs_t *
fileargs_init(int argc, char *argv[], int flags, mode_t mode,
cap_rights_t *rightsp, int operations);
fileargs_t *
fileargs_cinit(cap_channel_t *cas, int argc, char *argv[], int flags,
mode_t mode, cap_rights_t *rightsp, int operations);
fileargs_t *
fileargs_cinitnv(cap_channel_t *cas, nvlist_t *limits);
fileargs_t *
fileargs_initnv(nvlist_t *limits);
void
fileargs_free(fileargs_t *fa);
int
fileargs_lstat(fileargs_t *fa, const char *path, struct stat *sb);
int
fileargs_open(fileargs_t *fa, const char *name);
FILE *
fileargs_fopen(fileargs_t *fa, const char *name, const char *mode);
char *
fileargs_realpath(fileargs_t *fa, const char *pathname,
char *reserved_path);
π¦ DESCRIPTION π¦
so the cap_fileargs library exists to make Capsicum-izing your tools so much easier when those tools touch the file system. the whole idea, and I'm obsessed with it honestly: you pass along what's left of argv (with the count in argc), which holds the list of files your program should open. the library then spins up a service that serves those files for you. it's giving "main character energy" for your file descriptors π
π fileargs_init()
The function fileargs_init() creates a service to the system.fileargs. here's the vibe check on every argument:
argvcontains a list of files that should be opened. you can set it toNULLto create no service at all and prohibit every file from being opened β yes, that's a thing, and yes, it's on purpose.argcis the number of files passed to the program.flagsspecifies whether files can be opened for execution, for reading, and/or for writing.modespecifies the permissions to use when creating new files if theO_CREATflag is set.- for more info about the
flagsandmodearguments, go seeopen(2). rightspspecifies the capability rights that will be applied to restrict access to the files. more on capability rights incap_rights_init(3).operationsspecifies which operations are permitted when usingsystem.fileargs.
and these flags can be combined to form the operations value:
FA_OPENβ allowfileargs_open()andfileargs_fopen().FA_LSTATβ allowfileargs_lstat().FA_REALPATHβ allowfileargs_realpath().
π§ fileargs_cinit()
The function fileargs_cinit() behaves identically to fileargs_init(), but it requires an existing Casper connection to be passed as an argument. same energy, you just bring your own connection π«Ά
β fileargs_initnv() and fileargs_cinitnv()
The functions fileargs_initnv() and fileargs_cinitnv() are equivalent to fileargs_init() and fileargs_cinit() respectively, but they take their arguments in the form of an nvlist(9) structure. see the βLIMITSβ section for the deets on the expected argument types and values.
π fileargs_free()
The fileargs_free() function closes the connection to the system.fileargs service and frees all associated data structures. and good news: it safely handles NULL arguments. icon behavior, honestly.
π fileargs_lstat()
The function fileargs_lstat() provides the same functionality as lstat(2). that's it. that's the whole thing.
π fileargs_open() and fileargs_fopen()
The functions fileargs_open() and fileargs_fopen() behave identically to open(2) and fopen(3) respectively, except they retrieve their arguments from the fileargs_t structure. slay.
π₯ fileargs_realpath()
The function fileargs_realpath() provides the same functionality as the standard C library function realpath(3), resolving all symbolic links and references in a pathname. so many symlinks, so little time π«
π thread safety (read this one, bestie)
The following functions are reentrant but require synchronization for thread safety: fileargs_open(), fileargs_lstat(), fileargs_realpath(), fileargs_cinitnv(), fileargs_initnv(), and fileargs_fopen(). Multiple threads can call these functions safely only if they use different cap_channel_t arguments or proper synchronization mechanisms.
no cap: if you're going multi-threaded and you're not doing one of those two things, you're gonna have a bad time π
π LIMITS π
This section describes the required and optional arguments that must be passed to system.fileargs via the fileargs_initnv() and fileargs_cinitnv() functions using an nvlist(9) structure.
π The required ones (non-negotiable)
flags(NV_TYPE_NUMBER) β specifies access permissions for opened files.mode(NV_TYPE_NUMBER) β required when theO_CREATEflag is set inflags. specifies the permissions to use when creating new files.operations(NV_TYPE_NUMBER) β specifies which operations are allowed forsystem.fileargs. see the description of theoperationsargument infileargs_init()for possible values.
πΈ The optional ones (choose your own adventure)
cap_rights(NV_TYPE_BINARY) β thecap_rightsargument specifies the capability rights that will be applied to restrict access to opened files.filenames(NV_TYPE_NULL) β multipleNV_TYPE_NULLelements can be provided, where each element's name represents a file path that is allowed to be opened.
π§ EXAMPLES π§
okay here's a full example, and it's honestly kind of cute β look at this thing go:
int ch, fd, i;
cap_rights_t rights;
fileargs_t *fa;
while ((ch = getopt(argc, argv, "h")) != -1) {
switch (ch) {
case 'h':
default:
usage();
}
}
argc -= optind;
argv += optind;
/* Create capability to the system.fileargs service. */
fa = fileargs_init(argc, argv, O_RDONLY, 0,
cap_rights_init(&rights, CAP_READ), FA_OPEN);
if (fa == NULL)
err(1, "unable to open system.fileargs service");
/* Enter capability mode sandbox. */
if (cap_enter() < 0 && errno != ENOSYS)
err(1, "unable to enter capability mode");
/* Open files. */
for (i = 0; i < argc; i++) {
fd = fileargs_open(fa, argv[i]);
if (fd < 0)
err(1, "unable to open file %s", argv[i]);
printf("File %s opened in capability mode\n", argv[i]);
close(fd);
}
fileargs_free(fa);
like, look at that. sandboxed, files opened, everything cleaned up with fileargs_free(fa). periodt π
β¨
π«Ά SEE ALSO π«Ά
cap_enter(2), lstat(2), open(2), cap_rights_init(3), err(3), fopen(3), getopt(3), realpath(3), capsicum(4), nv(9)
β HISTORY β
The cap_fileargs service first appeared in FreeBSD 10.3. a lil throwback moment π
π AUTHORS π
Mariusz Zaborski <oshogbo@FreeBSD.org> β thank you for your service, king π
π BUGS π
The cap_fileargs service is considered experimental and should be thoroughly evaluated for risks before deploying in production environments.
listen to me: experimental means experimental. do your homework before you ship this to prod, bestie, I'm begging ππ
and that's the page!! this one's from Debian, dated August 8, 2025 β go forth and sandbox responsibly, ily, bye ππ¦πΈ
π¦ where this page comes from
- freebsd 15.1: base 15.1
- Copyright (c) 2018 Mariusz Zaborski <oshogbo@FreeBSD.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms