libpathrs v0.2.1 -- "やられたらやり返す。倍返しだ!"
This is a minor release of libpathrs which includes some fairly critical
bugfixes, as well as some Rust-specific packaging fixes that should make
it easier to use libpathrs in Rust projects.
Security
-
When using
ProcfsHandle::open_followon non-magic-link symlinks,
libpathrs could fall victim to an overmount attack because we had incorrectly
assumed that opening a symlink as a final component would be "atomic" (this
is only true for magic-links, which was the primary usecase we had in mind
for this API).We now try to use the safe procfs resolver even on symlinks to handle the
"regular symlink case". Note that (due to a separate bug in
ProcfsHandle::open_followthat has also been fixed), privileged users would
likely still get an error in this case.
Added
ErrorandErrorKindnow have acan_retryhelper that can be used to
make retry loops easier for callers.- libpathrs now has fairly comprehensive end-to-end tests for all our bindings
(written in a language-agnostic way), to ensure correctness and uniformty
when you use libpathrs, no matter which language you use.
Fixed
- python bindings: fix
pathrs.procfsexamples in README. - go bindings: fix the internal
os.FileModetoS_IF*conversion to not
auto-includeS_IFREGfor non-Mknodoperations (previously this would
causeMkdirAllto error out). Root::create_filenow supportsO_TMPFILE.- Previously, trying to use
ProcfsHandle::open_followwith a path whose
penultimate component was a symlink (i.e.,
ProcfsHandle::open_follow(ProcfsBase::ProcRoot, "self/status")) would
result in an error due to a mistake in how we handled looking up parent
directories. This has been fixed, and this will now work the way you expect
(though you should still useProcfsBase::ProcSelfinstead in the above
example). ProcfsHandle::open_followwas missing the logic to temporarily allocate a
non-subset=pidif the target does not exit. This ended up accidentally
mitigating theProcfsHandle::open_followsecurity issue mentioned above
(forfsopen(2)users trying to open symlinks inProcfsBase::ProcRoot--
note that onlyProcfsBase::ProcRootcontains such symlinks in the first
place).- Quite a few
Rootoperations that required resolving the parent directory of
the user-provided path could crash if passed/or return an unhelpful error
when passed.. We now return a proper error in these cases.
Changed
-
The
openat2resolver will now return-EAGAINif the number ofopenat2
retries is exceeded -- this allows higher-level users easily detect if an
error is an indication they should retry (based on their own retry policy).In addition, the number of retries done has been bumped from
32to128
based on some benchmarking which showed that32could fail up to 3% of the
time but128would only fail ~0.1% of the time in the worst case scenario
of an attacker that can saturate all cores withrename(2)operations.Users that need stronger resiliency guarantees can do their own additional
retry loop on top oflibpathrsby checking the return value forEAGAIN.
Please note that we would strongly recommend having some restriction to avoid
denial-of-service attacks (such as a deadline -- for reference, our testing
showed that even with >50k trials containing >200k operations a deadline of
1ms was never exceeded even in the most pessimistic attack scenario). -
The
O_PATHresolver forProcfsHandlewill now returnELOOPfor
magic-links that look likefoo:[bar]in order to better matchopenat2(2)
(examples includeanon_inode,nsfs,pipe, and other such special
inodes). Previously we would just returnENOENT.
Signed-off-by: Aleksa Sarai cyphar@cyphar.com