|
|
|
|
|
by shiomiru
206 days ago
|
|
> So even if one uses Cosmopolitan libc, if you link to some other library
that library may also do direct syscalls. And which syscalls is does, and
under which circumstances, is generally not part of the ABI promise. So this
can still break between semver patch version upgrades. Well but isn't that a more general problem with pledge? I can link to
libfoo, drop rpath privileges, and it'll work fine until libfoo starts
lazily loading /etc/fooconf (etc.) A nice thing about pledge is that it's modularized well enough so such
problems don't occur very often, but I'd argue it's not less common of an
issue than "libfoo started doing raw syscalls." The solution is also the
same: a) ask libfoo not to do it, or b) isolate libfoo in an auxiliary
process, or c) switch to libbar. > And at the very least you'll also be linking to libseccomp. :-) libseccomp proponents won't tell you this, but you can in fact use seccomp
without libseccomp, as does Cosmopolitan libc. All libseccomp does is
abstract away CPU architecture differences, which a libc already has to do
by itself anyway. (In my project, I got annoyed enough by the kernel header dependency that I
just replaced libseccomp with a shell script:
https://codeberg.org/bptato/chawan/src/commit/cad5664fc0aa10...
although this might have gotten me a place reserved in hell.) |
|
No, for two reasons: 1) pledge() lets you give high level "I just want to do I/O on what I already have", and it doesn't matter if new syscalls "openat2" (should be blocked) or "getrandom" (should be allowed) are created. (see the `newfstatat` example on printf). And 2) OpenBSD limits syscalls to be done from libc, and libc & kernel are released together. Other libs need to go through libc.
Yes, if libfoo starts doing actual behavioral changes like suddenly opening files, then that's inherently indistinguishable from a compromised process. But I don't think that we need to throw out the baby with that bathwater.
And it's not just about libfoo doing raw syscalls. `unveil()` allows blocking off the filesystem. And it'll apply to open, creat, openat, openat2, unlink, io_uring versions of the relevant calls (if OpenBSD had it), etc…
But yes, if libc could ship its best-effort pledge()/unveil(), that also blocks any further syscalls (in case the kernel is newer), that'd be great. But this needs to be part of (g)libc.
Though another problem is that it doesn't help child processes with a statically compiled newer libc, that quite reasonably wants to use the newer syscalls that the kernel has. OpenBSD decided to simply not support statically linked libc, but musl (and Cosmopolitan libc?) have that as an explicit goal.
So yeah, because they mandate syscalls from libc, ironically OpenBSD should have been able to make pledge/unveil a libc feature using a seccomp-like API, or hell, implemented entirely in user space. But Linux, which has that API, kinda can't.
(ok, so I don't know how strictly OpenBSD mandates the exact system libc, so maybe what I just said would open a vulnerability)