Skip to content

libpathrs v0.2.5 -- "Or, to save on postage, I'll just poison him with this!"

Latest

Choose a tag to compare

@cyphar cyphar released this 18 Jun 07:53
· 7 commits to main since this release
v0.2.5
0809083

Important

Due to the rising tide of supply chain attacks, we have stopped using
"Trusted" Publishing for our crates.io and PyPi releases. Their
UIs imply that such releases are "more trusted" but as the recent attacks
have shown, they actually grant your code forge's entire infrastructure the
right to release things on your behalf.

It would be nice if crates.io and PyPI supported a proper signing model
where developers control their keys, but that is sadly not the case today.
For PyPI, detached PGP keys in PyPI are basically security theatre
and PEP 480 has stalled; for crates.io there appears to be no
mechanism for signing your releases with a key you control directly!

Breaking

  • pathrs_inroot_hardlink and pathrs_inroot_symlink have been switched to
    using the standard argument order from their respective system calls
    (previously the order was swapped, which lead to possible confusion).
    • Previously compiled programs will continue to work (thanks to symbol
      versioning) but rebuilt programs will need to adjust their argument order.
    • Rust users are not affected by this change.
    • For the Go and Python bindings, the wrappers have also had their argument
      orders swapped to match the C API and so will also need to be updated when
      rebuilding. This is a very important point! Users must ensure that they
      use pre-0.2.5 bindings with pre-0.2.5 libpathrs library installs, and
      post-0.2.5 bindings with post-0.2.5 library installs. Mixing and
      matching them will cause bugs (most likely spurious ENOENT errors).
    • For the sake of future extensions (and to ease the migration),
      pathrs_inroot_hardlink now accepts both an old_root_fd and
      new_root_fd. At the moment, callers must pass the same value to both
      arguments (this means the same numeric file descriptor value, not just a
      reference to the same underlying file).
      • The Go and Python bindings for pathrs_inroot_hardlink have not had
        their APIs changed, and so they still only permit operating within a
        single root.
  • pathrs_inroot_rename also now accepts both an old_root_fd and
    new_root_fd, with the same caveats as pathrs_inroot_hardlink above.
    • The Go and Python bindings for pathrs_inroot_rename have not had their
      APIs changed, and so they still only permit operating within a single
      root.
  • RenameFlags is now backed by a u64 (instead of libc::c_uint) so that we
    can accommodate future extension bits beyond the kernel's current 32-bit ABI.
    Rust callers using RenameFlags::bits() or storing the raw value will need
    to adjust their types.
    • As part of this, pathrs_inroot_rename now also takes a uint64_t, and
      thus the the Go (*Root).Rename wrapper takes a uint64 as well.
  • OpenFlags is now backed by a u64 (instead of libc::c_int), as recent
    kernel changes such as OPENAT2_REGULAR will likely start to use some of the
    upper flag bits available from openat2(2). This has an impact on all C APIs
    (and thus Go bindings) that accept OpenFlags arguments (we do provide old
    symbol versions to ease the transition):
    • pathrs_reopen
    • pathrs_inroot_open
    • pathrs_inroot_creat
    • pathrs_proc_open
    • pathrs_proc_openat

Added

  • capi: We now have a new pathrs_version API that provides runtime version
    information, which loosely matches other libraries like libseccomp. The API
    is based on extensible structs, so we can add more information here in the
    future.
  • install.sh now supports --disable-static and --disable-dynamic to limit
    what files are installed (their --enable-* inverses are also available for
    completeness, but they both are enabled by default).

Fixed

  • Containers often have /proc/sys overmounted with a read-only mount to avoid
    container escapes, this caused the O_PATH resolver to panic because the
    hardened procfs lookup for /proc/sys/fs/protected_symlinks would fail. We
    now conservatively assume that fs.protected_symlinks is enabled if we
    cannot access the file for any reason.

    This also causes attempts to access /proc/sys files using ProcfsHandle to
    also fail (by design). In the future we plan to provide some quality-of-life
    improvements to permit access in those cases, but at the moment users need to
    be aware that those kinds of accesses can fail.

  • Root::readlink and ProcfsHandle::readlink would previously return
    ENOENT if the target path existed but was not a symlink. This occurred
    because of a peculiar asymmetry in the kernel APIs for readlinkat(2), but
    users found it confusing and so we now remap the error in that case to
    EINVAL (as you would get from readlink(2) with a path). This will make it
    easier to distinguish the "target path does not exist" and "target path is
    not a symlink" cases.

Thanks to the following contributors who made this release possible:

Signed-off-by: Aleksa Sarai cyphar@cyphar.com