Date: Tue, 13 Feb 2024 16:22:45 +0000 From: Jonathan Adams <jfadams1963@proton.me> To: FreeBSD-questions <freebsd-questions@freebsd.org> Subject: Limiting Capsicum capabilities rights Message-ID: <dJKkcWGRRitAKnm4TMmvn9DevzBmK6viLJEfk3rpDha3d4D3mUGXxrVXSmoY_vYNbrpmk4Ji3AowUOYLoY4x5XOmIlkBr6TjUX_beP5bQnI=@proton.me>
next in thread | raw e-mail | index | archive | help
This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --------83c87a14859d359eade09ca939598bfe5e98ce0aa19b69f87e901f89d44136f1 Content-Type: multipart/mixed;boundary=---------------------1b2a7518afbbd019d47cabefdd25af47 -----------------------1b2a7518afbbd019d47cabefdd25af47 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain;charset=utf-8 Hi all, I'm learning to use capability mode, and am having some difficulty under= standing how to correctly limit the rights. I've been doing a lot of readi= ng, watching video (Mariusz Zaborski's BSDcan talk from 2016), and a lot o= f experimenting. According to rights(4), when a file descriptor is created= , it is granted all the rights. I'm having trouble limiting the rights so = that it all works with the bare minimum of rights. In my test program, I can successfully do the following since all rights a= re granted: + first get a directory file descriptor for cwd + call cap_enter() + while in the sandbox, call a function that does: - call openat() and fdopen() to open an input file read-only - call openat() and fdopen() to open an output file read-write - read from in - write to out (which sets weird file perms!) - exit function - fix weird file perms with fchmodat() + done Relevant code snippets: ---------- 45 =E2=94=82 // Get cwd 46 =E2=94=82 if (getcwd(cwd, sizeof(cwd)) =3D=3D NULL) { 47 =E2=94=82 perror("getcwd() error"); 48 =E2=94=82 return 1; 49 =E2=94=82 } ... 76 =E2=94=82 // Get fd for current directory 77 =E2=94=82 dirfd =3D open(cwd, O_RDONLY | O_DIRECTORY); ... 91 =E2=94=82 // Enter capability mode 92 =E2=94=82 if (cap_enter() < 0 && errno !=3D ENOSYS) { 93 =E2=94=82 err(1, "Unable to enter capability mode"); 94 =E2=94=82 // Clean up code 95 =E2=94=82 return 1; 96 =E2=94=82 } ... // call function that does stuff with reading and writing fil= es 113 =E2=94=82 // Clean up file permissions 114 =E2=94=82 if (fchmodat(dirfd, outfn, fmode, AT_RESOLVE_BENEATH)= =3D=3D -1) { 115 =E2=94=82 printf("chmod 0640 on %s failed.\n", outfn); 116 =E2=94=82 perror(""); 117 =E2=94=82 } 118 =E2=94=82 119 =E2=94=82 return 0; 120 =E2=94=82 } ---------- As I say, this all works fine. But if I add in the following declaration= and calls to set and limit rights, it fails; clearly too restrictive: ---------- 28 =E2=94=82 cap_rights_t rights; ... 86 =E2=94=82 // Set rights on directory fd 87 =E2=94=82 cap_rights_init(&rights, CAP_LOOKUP, CAP_CREATE, CAP_= PREAD, \ 88 =E2=94=82 CAP_PWRITE, CAP_FCHMOD); 89 =E2=94=82 cap_rights_limit(dirfd, &rights); ---------- With my error messages turned on, I see that adding CAP_LOOKUP to the ri= ghts mask, (as per rights(4)), allows openat() to succeed, but fdopen() st= ill fails and I'm not sure which right is needed for fdopen() to succeed: ---------- Trying: ifd =3D openat(dirfd, infn, O_RDONLY) : No error: 0 ifd =3D 4 Trying: in =3D fdopen(ifd, "r") : Capabilities insufficient in =3D 0 Could not open input file for reading. : Capabilities insufficient Cleaning up and exiting gracefully. ---------- Also, from openat(2): ---------- In capsicum(4) capability mode, open() is not permitted. The path argument to openat() must be strictly relative to a file descriptor f= d. path must not be an absolute path and must not contain ".." component= s which cause the path resolution to escape the directory hierarchy starting at fd. Additionally, no symbolic link in path may target absolute path or contain escaping ".." components. fd must not be ^^^^^^^^^^^^^^ AT_FDCWD. ^^^^^^^^ ---------- Do I read this correctly that the directory file descriptor can _not_ be= for the cwd? If so, that's confusing me as I am clearly using the cwd, an= d it works with all right granted. Or does it mean that you can't use the = AT_FDCWD flag as 'fd'? Any enlightenment or pointing-me-in-the-right-direction is greatly appreci= ated. Thanks in advance! - Jonathan ____________________________________________ "Before Turing, things were done to numbers. After Turing, numbers began doing things" - George Dyson -----------------------1b2a7518afbbd019d47cabefdd25af47-- --------83c87a14859d359eade09ca939598bfe5e98ce0aa19b69f87e901f89d44136f1 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: ProtonMail wnUEARYKACcFgmXLlywJkI6O/sbt8r3IFiEEcBGzOO9wDbcpT/10jo7+xu3y vcgAAJTVAQDUXExxdV+ZsvC7+tYRLYoCprOBFiXMCF1CTezMH0pO1QEAtHV7 qDQSvilIT/KqBJ2xCaED8CcW6XU16ZsfRzFGgAI= =Pmv5 -----END PGP SIGNATURE----- --------83c87a14859d359eade09ca939598bfe5e98ce0aa19b69f87e901f89d44136f1--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?dJKkcWGRRitAKnm4TMmvn9DevzBmK6viLJEfk3rpDha3d4D3mUGXxrVXSmoY_vYNbrpmk4Ji3AowUOYLoY4x5XOmIlkBr6TjUX_beP5bQnI=>