Skip to content

Tags

Tags give the ability to mark specific points in history as being important
  • upstream/0.6.0

    Upstream version 0.6.0
  • v0.6.0

    60da611d · VERSION: release v0.6.0 ·
    github.com/cyphar/filepath-securejoin v0.6.0 -- "By the Power of Greyskull!"
    
    While quite small code-wise, this release marks a very key point in the
    development of filepath-securejoin.
    
    filepath-securejoin was originally intended (back in 2017) to simply be
    a single-purpose library that would take some common code used in
    container runtimes (specifically, Docker's FollowSymlinksInScope) and
    make it more general-purpose (with the eventual goals of it ending up in
    the Go stdlib).
    
    Of course, I quickly discovered that this problem was actually far more
    complicated to solve when dealing with racing attackers, which lead to
    me developing openat2(2) and libpathrs. I had originally planned for
    libpathrs to completely replace filepath-securejoin "once it was ready"
    but in the interim we needed to fix several race attacks in runc as part
    of security advisories. Obviously we couldn't require the usage of a
    pre-0.1 Rust library in runc so it was necessary to port bits of
    libpathrs into filepath-securejoin. (Ironically the first prototypes of
    libpathrs were originally written in Go and then rewritten to Rust, so
    the code in filepath-securejoin is actually Go code that was rewritten
    to Rust then re-rewritten to Go.)
    
    It then became clear that pure-Go libraries will likely not be willing
    to require CGo for all of their builds, so it was necessary to accept
    that filepath-securejoin will need to stay. As such, in v0.5.0 we
    provided more pure-Go implementations of features from libpathrs but
    moved them into "pathrs-lite" subpackage to clarify what purpose these
    helpers serve.
    
    This release finally closes the loop and makes it so that pathrs-lite
    can transparently use libpathrs (via a "libpathrs" build-tag). This
    means that upstream libraries can use the pure Go version if they
    prefer, but downstreams (either downstream library users or even
    downstream distributions) are able to migrate to libpathrs for all
    usages of pathrs-lite in an entire Go binary.
    
    I should make it clear that I do not plan to port the rest of libpathrs
    to Go, as I do not wish to maintain two copies of the same codebase.
    pathrs-lite already provides the core essentials necessary to operate on
    paths safely for most modern systems. Users who want additional
    hardening or more ergonomic APIs are free to use "cyphar.com/go-pathrs"
    (libpathrs's Go bindings).
    
    Breaking:
    
    - The deprecated MkdirAll, MkdirAllHandle, OpenInRoot, OpenatInRoot and
      Reopen wrappers have been removed. Please switch to using pathrs-lite
      directly.
    
    Added:
    
    - pathrs-lite now has support for using libpathrs as a backend. This is
      opt-in and can be enabled at build time with the "libpathrs" build
      tag. The intention is to allow for downstream libraries and other
      projects to make use of the pure-Go "filepath-securejoin/pathrs-lite"
      package and distributors can then opt-in to using libpathrs for the
      entire binary if they wish.
    
    Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
    
  • debian/0.4.1-2

    29c6dee3 · debian/changelog: update ·
    golang-github-cyphar-filepath-securejoin release 0.4.1-2 for unstable
    
    [dgit distro=debian split --quilt=gbp]
    [dgit please-upload source=golang-github-cyphar-filepath-securejoin version=0.4.1-2 upstream-tag=upstream/0.4.1 upstream=9fa24e6b307912eac1da82840e7be8fe2207152f]
    
  • debian/0.4.1-1

    golang-github-cyphar-filepath-securejoin Debian release 0.4.1-1
  • upstream/0.4.1

    Upstream version 0.4.1
  • v0.5.1

    ee2f5bef · VERSION: release v0.5.1 ·
    github.com/cyphar/filepath-securejoin v0.5.1 -- "Spooky scary skeletons send shivers down your spine!"
    
    This release includes a few minor improvements to the openat2 retry
    logic, to try to make it a little easier for programs to deal with
    spurious EAGAIN errors.
    
    Changed:
    
    - openat2 can return -EAGAIN if it detects a possible attack in certain
      scenarios (namely if there was a rename or mount while walking a path
      with a ".." component). While this is necessary to avoid a
      denial-of-service in the kernel, it does require retry loops in
      userspace.
    
      In previous versions, pathrs-lite would retry openat2 32 times before
      returning an error, but we've received user reports that this limit
      can be hit on systems with very heavy load. In some synthetic
      benchmarks (testing the worst-case of an attacker doing renames in a
      tight loop on every core of a 16-core machine) we managed to get a ~3%
      failure rate in runc. We have improved this situation in two ways:
    
      * We have now increased this limit to 128, which should be good enough
        for most use-cases without becoming a denial-of-service vector (the
        number of syscalls called by the O_PATH resolver in a typical case
        is within the same ballpark). The same benchmarks show a failure
        rate of ~0.12% which (while not zero) is probably sufficient for
        most users.
    
      * In addition, we now return a unix.EAGAIN error that is bubbled up
        and can be detected by callers. This means that callers with
        stricter requirements to avoid spurious errors can choose to do
        their own infinite EAGAIN retry loop (though we would strongly
        recommend users use time-based deadlines in such retry loops to
        avoid potentially unbounded denials-of-service).
    
    Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
    
  • v0.5.0

    bb9e81fe · VERSION: release 0.5.0 ·
    github.com/cyphar/filepath-securejoin v0.5.0 -- "Let the past die. Kill it if you have to."
    
    ========================================================================
    NOTE: With this release, some parts of filepath-securejoin are now
          licensed under the Mozilla Public License (version 2). Please see
          COPYING.md as well as the the license header in each file for more
          details.
    ========================================================================
    
    Breaking:
    
    - The new API introduced in the 0.3.0 release has been moved to a new
      subpackage called "pathrs-lite". This was primarily done to better
      indicate the split between the new and old APIs, as well as indicate
      to users the purpose of this subpackage (it is a less complete version
      of libpathrs).
    
      We have added some wrappers to the top-level package to ease the
      transition, but those are deprecated and will be removed in the next
      minor release of filepath-securejoin. Users should update their import
      paths.
    
      This new subpackage has also been relicensed under the Mozilla Public
      License (version 2), please see COPYING.md for more details.
    
    Added:
    
    - Most of the key bits the safe procfs API have now been exported and
      are available in .../filepath-securejoin/pathrs-lite/procfs. At the
      moment this primarily consists of a new procfs.Handle API:
    
       * OpenProcRoot returns a new handle to /proc, endeavouring to make it
         safe if possible ("subset=pid" to protect against mistaken write
         attacks and leaks, as well as using fsopen(2) to avoid racing mount
         attacks).
    
         OpenUnsafeProcRoot returns a handle without attempting to create
         one with "subset=pid", which makes it more dangerous to leak. Most
         users should use OpenProcRoot (even if you need to use ProcRoot as
         the base of an operation, as filepath-securejoin will internally
         open a temporary OpenUnsafeProcRoot handle when necessary).
    
       * The (*procfs.Handle).Open* family of methods lets you get a safe
         O_PATH handle to subpaths within /proc for certain subpaths.
    
         For OpenThreadSelf, the returned ProcThreadSelfCloser needs to be
         called after you completely finish using the handle (this is
         necessary because Go is multi-threaded and ProcThreadSelf
         references /proc/thread-self which may disappear if we do not
         runtime.LockOSThread -- ProcThreadSelfCloser is currently
         equivalent to runtime.UnlockOSThread).
    
         Note that you cannot open any procfs symlinks (most notably
         magic-links) using this API. At the moment, filepath-securejoin
         does not support this feature (but libpathrs does).
    
       * ProcSelfFdReadlink lets you get the in-kernel path representation
         of a file descriptor (think readlink("/proc/self/fd/...")), except
         that we verify that there aren't any tricky overmounts that could
         fool the process.
    
         Please be aware that the returned string is simply a snapshot at
         that particular moment, and an attacker could move the file being
         pointed to. In addition, complex namespace configurations could
         result in non-sensical or confusing paths to be returned. The value
         received from this function should only be used as secondary
         verification of some security property, not as proof that a
         particular handle has a particular path.
    
      The procfs handle used internally by the API is the same as the rest
      of filepath-securejoin (for privileged programs this is usually a
      private in-process procfs instance created with fsopen(2)).
    
      As before, this is intended as a stop-gap before users migrate to
      libpathrs, which provides a far more extensive safe procfs API and is
      generally more robust.
    
    - Previously, the hardened procfs implementation (used internally within
      Reopen and Open(at)InRoot) only protected against overmount attacks on
      systems with openat2(2) (Linux 5.6) or systems with fsopen(2) or
      open_tree(2) (Linux 5.2) and programs with privileges to use them
      (with some caveats about locked mounts that probably affect very few
      users). For other users, an attacker with the ability to create
      malicious mounts (on most systems, a sysadmin) could trick you into
      operating on files you didn't expect. This attack only really makes
      sense in the context of container runtime implementations.
    
      This was considered a reasonable trade-off, as the long-term intention
      was to get all users to just switch to libpathrs if they wanted to use
      the safe procfs API (which had more extensive protections, and is what
      these new protections in filepath-securejoin are based on). However,
      as the API is now being exported it seems unwise to advertise the API
      as "safe" if we do not protect against known attacks.
    
      The procfs API is now more protected against attackers on systems
      lacking the aforementioned protections. However, the most
      comprehensive of these protections effectively rely on
      statx(STATX_MNT_ID) (Linux 5.8). On older kernel versions, there is no
      effective protection (there is some minimal protection against
      non-procfs filesystem components but a sufficiently clever attacker
      can work around those). In addition, STATX_MNT_ID is vulnerable to
      mount ID reuse attacks by sufficiently motivated and privileged
      attackers -- this problem is mitigated with STATX_MNT_ID_UNIQUE (Linux
      6.8) but that raises the minimum kernel version for more protection.
    
      The fact that these protections are quite limited despite needing a
      fair bit of extra code to handle was one of the primary reasons we did
      not initially implement this in filepath-securejoin (libpathrs
      supports all of this, of course).
    
    Fixed:
    
    - RHEL 8 kernels have backports of fsopen(2) but in some testing we've
      found that it has very bad (and very difficult to debug) performance
      issues, and so we will explicitly refuse to use fsopen(2) if the
      running kernel version is pre-5.2 and will instead fallback to
      open("/proc").
    
    Thanks to the following contributors who made this release possible:
    
     * Aleksa Sarai <cyphar@cyphar.com>
     * Kir Kolyshkin <kolyshkin@gmail.com>
     * Stephen Kitt <skitt@redhat.com>
    
    Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
    
  • v0.4.1

    7abd8704 · VERSION: release v0.4.1 ·
    github.com/cyphar/filepath-securejoin v0.4.1
    
    This release fixes a regression introduced in one of the hardening
    features added to filepath-securejoin 0.4.0.
    
    - The restrictions added for root paths passed to SecureJoin in 0.4.0
      was found to be too strict and caused some regressions when folks
      tried to update, so this restriction has been relaxed to only return
      an error if the path contains a ".." component. We still recommend
      users use filepath.Clean (and even filepath.EvalSymlinks) on the root
      path they are using, but at least you will no longer be punished for
      "trivial" unclean paths.
    
    Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
    
  • v0.4.0

    9a17e6b8 · VERSION: release v0.4.0 ·
    github.com/cyphar/filepath-securejoin v0.4.0
    
    This release primarily includes a few minor breaking changes to make the
    MkdirAll and SecureJoin interfaces more robust against accidental
    misuse.
    
    - SecureJoin(VFS) will now return an error if the provided root is not a
      filepath.Clean'd path.
    
      While it is ultimately the responsibility of the caller to ensure the
      root is a safe path to use, passing a path like /symlink/.. as a root
      would result in the SecureJoin'd path being placed in / even though
      /symlink/.. might be a different directory, and so we should more
      strongly discourage such usage.
    
      All major users of securejoin.SecureJoin already ensure that the paths
      they provide are safe (and this is ultimately a question of user
      error), but removing this foot-gun is probably a good idea. Of course,
      this is necessarily a breaking API change (though we expect no real
      users to be affected by it).
    
      Thanks to Erik Sjölund, who initially reported this issue as a
      possible security issue.
    
    - MkdirAll and MkdirHandle now take an os.FileMode-style mode argument
      instead of a raw unix.S_*-style mode argument, which may cause
      compile-time type errors depending on how you use filepath-securejoin.
      For most users, there will be no change in behaviour aside from the
      type change (as the bottom 0o777 bits are the same in both formats,
      and most users are probably only using those bits).
    
      However, if you were using unix.S_ISVTX to set the sticky bit with
      MkdirAll(Handle) you will need to switch to os.ModeSticky otherwise
      you will get a runtime error with this update. In addition, the error
      message you will get from passing unix.S_ISUID and unix.S_ISGID will
      be different as they are treated as invalid bits now (note that
      previously passing said bits was also an error).
    
    Thanks to the following contributors for helping make this release
    possible:
    
     * Aleksa Sarai <cyphar@cyphar.com>
     * Erik Sjölund <erik.sjolund@gmail.com>
    
    Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
    
  • v0.3.6

    200008ed · VERSION: release v0.3.6 ·
    github.com/cyphar/filepath-securejoin v0.3.6
    
    This release lowers the minimum Go version to Go 1.18 as well as some
    library dependencies, in order to make it easier for folks that need to
    backport patches using the new filepath-securejoin API onto branches
    that are stuck using old Go compilers. For users using Go >= 1.21, this
    release contains no functional changes.
    
    * The minimum Go version requirement for filepath-securejoin is now Go 1.18
      (we use generics internally).
    
      For reference, filepath-securejoin@v0.3.0 somewhat-arbitrarily bumped the
      Go version requirement to 1.21.
    
      While we did make some use of Go 1.21 stdlib features (and in principle Go
      versions <= 1.21 are no longer even supported by upstream anymore), some
      downstreams have complained that the version bump has meant that they have to
      do workarounds when backporting fixes that use the new filepath-securejoin
      API onto old branches. This is not an ideal situation, but since using this
      library is probably better for most downstreams than a hand-rolled
      workaround, we now have compatibility shims that allow us to build on older
      Go versions.
    
    * Lower minimum version requirement for golang.org/x/sys to v0.18.0 (we
      need the wrappers for fsconfig(2)), which should also make backporting
      patches to older branches easier.
    
    Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
    
  • v0.3.5

    e60739b5 · VERSION: release v0.3.5 ·
    github.com/cyphar/filepath-securejoin v0.3.5
    
    This release primarily includes a fix for an issue involving two
    programs racing to MkdirAll the same directory, which caused a
    regression with BuildKit.
    
    - `MkdirAll` will now no longer return an `EEXIST` error if two racing
      processes are creating the same directory. We will still verify that the path
      is a directory, but this will avoid spurious errors when multiple threads or
      programs are trying to `MkdirAll` the same path. opencontainers/runc#4543
    
    Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
    
  • archive/debian/0.3.4-3

    golang-github-cyphar-filepath-securejoin release 0.3.4-3 for unstable (sid) [dgit]
    
    [dgit distro=debian split --quilt=gbp]
    
  • debian/0.3.4-3

    golang-github-cyphar-filepath-securejoin release 0.3.4-3 for unstable (sid)
    
    (maintainer view tag generated by dgit --quilt=gbp)
    
    [dgit distro=debian split --quilt=gbp]
    
  • archive/debian/0.3.4-2

    golang-github-cyphar-filepath-securejoin release 0.3.4-2 for unstable (sid) [dgit]
    
    [dgit distro=debian split --quilt=gbp]
    
  • debian/0.3.4-2

    golang-github-cyphar-filepath-securejoin release 0.3.4-2 for unstable (sid)
    
    (maintainer view tag generated by dgit --quilt=gbp)
    
    [dgit distro=debian split --quilt=gbp]
    
  • archive/debian/0.3.4-1

    golang-github-cyphar-filepath-securejoin release 0.3.4-1 for unstable (sid) [dgit]
    
    [dgit distro=debian no-split --quilt=linear]
    
  • debian/0.3.4-1

    golang-github-cyphar-filepath-securejoin release 0.3.4-1 for unstable (sid) [dgit]
    
    [dgit distro=debian no-split --quilt=linear]
    
  • upstream/0.3.4

    Upstream version 0.3.4
  • v0.3.4

    fd16ade2 · VERSION: release v0.3.4 ·
    github.com/cyphar/filepath-securejoin v0.3.4
    
    This release primarily includes a fix that blocked using
    filepath-securejoin in Kubernetes.
    
    - Previously, some testing mocks we had resulted in us doing import "testing"
      in non-_test.go code, which made some downstreams like Kubernetes unhappy.
      This has been fixed. (#32)
    
    Thanks to all of the contributors who made this release possible:
    
     * Aleksa Sarai <cyphar@cyphar.com>
     * Stephen Kitt <skitt@redhat.com>
    
    Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
    
  • v0.3.3

    93cff46c · VERSION: release v0.3.3 ·
    github.com/cyphar/filepath-securejoin v0.3.3
    
    This release primarily includes fixes for spurious errors we hit when
    checking that directories created by MkdirAll "look right". Upon further
    consideration, these checks were fundamentally buggy and didn't offer
    any practical protection anyway.
    
    - The mode and owner verification logic in `MkdirAll` has been removed. This
      was originally intended to protect against some theoretical attacks but upon
      further consideration these protections don't actually buy us anything and
      they were causing spurious errors with more complicated filesystem setups.
    - The "is the created directory empty" logic in `MkdirAll` has also been
      removed. This was not causing us issues yet, but some pseudofilesystems (such
      as `cgroup`) create non-empty directories and so this logic would've been
      wrong for such cases.
    
    Thanks to all of the contributors who made this release possible:
    
     * Aleksa Sarai <cyphar@cyphar.com>
     * Kir Kolyshkin <kolyshkin@gmail.com>
    
    Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>