Commit Graph

7710 Commits

Author SHA1 Message Date
Aleksa Sarai c2bde92ce8 libct: switch final WithProcfd users to WithProcfdFile
This probably should've been done as part of commit d40b3439a9
("rootfs: switch to fd-based handling of mountpoint targets") but it
seems I missed them when doing the rest of the conversions.

This also lets us remove utils.WithProcfd entirely, as well as
pathrs.MkdirAllInRoot. Unfortunately, WithProcfd was exposed in the
externally-importable "libcontainer/utils" package and so we need to
have a deprecation notice to remove it in runc 1.5.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(cherry picked from commit 9dbd37e06f)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-26 21:05:37 +11:00
Aleksa Sarai 50aa47ba69 libcontainer: move CleanPath and StripRoot to internal/pathrs
These helpers will be needed for the compatibility code added in future
patches in this series, but because "internal/pathrs" is imported by
"libcontainer/utils" we need to move them so that we can avoid circular
dependencies.

Because the old functions were in a non-internal package it is possible
some downstreams use them, so add some wrappers but mark them as
deprecated.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(cherry picked from commit 42a1e19d67)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-26 21:05:37 +11:00
Akihiro Suda ffc11bcff5 Merge pull request #5034 from lifubang/ci-detect-fdleak-try-best-1.4
[1.4] fix fd leaks and detect them as comprehensively as possible
2025-11-26 12:48:08 +09:00
lifubang e675743f06 integration: verify syscall compatibility after seccomp enforcement
Signed-off-by: lifubang <lifubang@acmcoder.com>
(cherry picked from commit d8706501cf)
Signed-off-by: lifubang <lifubang@acmcoder.com>
2025-11-20 11:53:07 +00:00
lifubang f52ffd18d1 bump github.com/cyphar/filepath-securejoin from 0.6.0 to 0.6.1
Signed-off-by: lifubang <lifubang@acmcoder.com>
(cherry picked from commit 0127cc650928156cb1fb43a02705926c445ed0c1)
Signed-off-by: lifubang <lifubang@acmcoder.com>
2025-11-20 11:53:03 +00:00
lifubang 0ec8f1abd5 libct: add a defer fd close in createDeviceNode
Signed-off-by: lifubang <lifubang@acmcoder.com>
(cherry picked from commit 9a5e6262f0bf4e3e654b1a0d71bb804093948f85)
Signed-off-by: lifubang <lifubang@acmcoder.com>
2025-11-20 11:53:03 +00:00
lifubang 612dbb942c libct: always close m.dstFile in mountToRootfs
Signed-off-by: lifubang <lifubang@acmcoder.com>
(cherry picked from commit e0272886047915899ec06e06665723fc453d3cbf)
Signed-off-by: lifubang <lifubang@acmcoder.com>
2025-11-20 11:53:03 +00:00
lifubang 9f84cce9ba ci: detect file descriptor leaks as comprehensively as possible
Co-authored-by: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: lifubang <lifubang@acmcoder.com>
(cherry picked from commit ba7f46d7119dc4bf57e2a13017333d1980494ea9)
Signed-off-by: lifubang <lifubang@acmcoder.com>
2025-11-20 11:53:03 +00:00
lfbzhm 9a05ab7cc2 Merge pull request #5000 from kolyshkin/1.4-check-go
[1.4] check go version from Dockerfile
2025-11-20 17:52:02 +08:00
lfbzhm 2fed6833ff Merge pull request #5011 from kolyshkin/1.4-4948
[1.4] docs/spec-conformance.md: update for spec v1.3.0
2025-11-20 12:46:05 +08:00
Kir Kolyshkin 896c4beaec ci: add checking Go version from Dockerfile
This is to ensure that Go version in Dockerfile (which is used to build
release binaries) is:
 - currently supported;
 - used in CI tests.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit df4acc8867)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-11-20 12:43:40 +08:00
Kir Kolyshkin cb401641e5 ci: faster git clone
For some reason, some jobs in .github/workflows/validate.yml
have "fetch-depth: 0" argument to actions/checkout, meaning
"all history for all branches and tags". Obviously this is
not needed here.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit e0b00171eb0f338cf024760019abdd4e7dec690f)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-11-20 12:43:40 +08:00
Akihiro Suda 77c79c566f docs/spec-conformance.md: update for spec v1.3.0
ref: opencontainers/runtime-spec PR 1302

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(cherry picked from commit 653161f6d8)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-11-20 14:16:43 +11:00
lfbzhm f9f0369f1f Merge pull request #5030 from cyphar/1.4-5017-ci-pin-parent-cgroup
[1.4] ci: ensure the cgroup parent always exists for rootless
2025-11-20 09:15:03 +08:00
lifubang 2702f9bfbc ci: ensure the cgroup(v1) parent always exists for rootless
On some systems (e.g., AlmaLinux 8), systemd automatically removes cgroup paths
when they become empty (i.e., contain no processes). To prevent this, we spawn
a dummy process to pin the cgroup in place.
Fix: https://github.com/opencontainers/runc/issues/5003

Signed-off-by: lifubang <lifubang@acmcoder.com>
(cherry picked from commit bba7647d09)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-20 03:28:43 +11:00
Akihiro Suda e3bfca3b56 Merge pull request #5004 from cyphar/1.4-pids-limit-0
[1.4] runtime-spec: update pids.limit handling to match new guidance
2025-11-18 13:43:09 +09:00
Kir Kolyshkin c5528aba2f Merge pull request #5006 from cyphar/1.4-deprecate-cgroupv1
[1.4] Deprecate cgroup v1
2025-11-13 13:21:44 -08:00
Akihiro Suda 62014ed9d4 Deprecate cgroup v1
For issue 4955

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
(cherry picked from commit 1cdfc0def9)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-12 20:18:54 +11:00
Aleksa Sarai 41e6b4f077 update: switch to generics for mkPtr logic
This is much easier to read and removes the need for explicit per-type
helper functions.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(cherry picked from commit 8ab2458bc4)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-12 20:07:00 +11:00
Aleksa Sarai 88e3b11467 tests: add pids.limit tests
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(cherry picked from commit 72421e0e25)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-12 20:07:00 +11:00
Aleksa Sarai 24dff91a09 runtime-spec: update pids.limit handling to match new guidance
The main update is actually in github.com/opencontainers/cgroups, but we
need to also update runtime-spec to a newer pre-release version to get
the updates from there as well.

In short, the behaviour change is now that "0" is treated as a valid
value to set in "pids.max", "-1" means "max" and unset/nil means "do
nothing". As described in the opencontainers/cgroups PR, this change is
actually backwards compatible because our internal state.json stores
PidsLimit, and that entry is marked as "omitempty". So, an old runc
would omit PidsLimit=0 in state.json, and this will be parsed by a new
runc as being "nil" -- and both would treat this case as "do not set
anything".

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(cherry picked from commit 3b75374cc7)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-12 20:07:00 +11:00
Aleksa Sarai e3fbc19db7 Merge pull request #4995 from kolyshkin/1.4-4970
[1.4] disable golangci-lint cache
2025-11-11 15:04:41 +11:00
lfbzhm 80cfbe4d27 Merge pull request #4976 from cyphar/1.4-tmpfs-mode
[1.4] rootfs: only set mode= for tmpfs mount if target already existed
2025-11-11 09:26:44 +08:00
lfbzhm b604bc8b98 Merge pull request #4980 from cyphar/1.4-selinux-1.13
[1.4] deps: update to github.com/opencontainers/selinux@v0.13.0
2025-11-11 09:24:49 +08:00
dependabot[bot] 3938a5675b build(deps): bump golangci/golangci-lint-action from 8 to 9
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 8 to 9.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v8...v9)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-version: '9'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit c0db4632d2)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-11-10 15:49:04 -08:00
Kir Kolyshkin 37fca442a5 ci: bump golangci-lint to v2.6
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 49780ce734)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-11-10 15:48:30 -08:00
Kir Kolyshkin 79848d81c8 ci: disable golangci-lint cache
This will result in slower runs but we are having issues with
golangci-lint (false positives) that are most probably related
to caching.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 96dfa9de54)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-11-10 15:48:20 -08:00
Aleksa Sarai fbf9e99e5c rootfs: only set mode= for tmpfs mount if target already existed
This was always the intended behaviour but commit 72fbb34f50 ("rootfs:
switch to fd-based handling of mountpoint targets") regressed it when
adding a mechanism to create a file handle to the target if it didn't
already exist (causing the later stat to always succeed).

A lot of people depend on this functionality, so add some tests to make
sure we don't break it in the future.

Fixes: 72fbb34f50 ("rootfs: switch to fd-based handling of mountpoint targets")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(cherry picked from commit 9a9719eeb4)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-11 03:11:56 +11:00
Aleksa Sarai 58afaa3fe6 deps: update to github.com/opencontainers/selinux@v0.13.0
This new version includes the fixes for CVE-2025-52881, so we can remove
the internal/third_party copy of the library we added in commit
ed6b1693b8 ("selinux: use safe procfs API for labels") as well as the
"replace" directive in go.mod (which is problematic for "go get"
installs).

Fixes: ed6b1693b8 ("selinux: use safe procfs API for labels")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(cherry picked from commit 96f1962f91)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-08 02:20:20 +11:00
lfbzhm 991d12159f Merge pull request #4967 from cyphar/1.4-4964-fix-mips
[1.4] libct: fix mips compilation
2025-11-06 11:54:52 +08:00
Kir Kolyshkin 3617bd0562 libct: fix mips compilation
On MIPS arches, Rdev is uint32 so we have to convert it.

Fixes issue 4962.

Fixes: 8476df83 ("libct: add/use isDevNull, verifyDevNull")
Fixes: de87203e ("console: verify /dev/pts/ptmx before use")
Fixes: 398955bc ("console: add fallback for pre-TIOCGPTPEER kernels")
Reported-by: Tianon Gravi <admwiggin@gmail.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 1b954f1f06)
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-06 13:46:51 +11:00
Aleksa Sarai eed8ce2422 merge security release into opencontainers/runc:release-1.4
Aleksa Sarai (24):
  VERSION: back to development
  VERSION: release v1.4.0-rc.3
  rootfs: re-allow dangling symlinks in mount targets
  openat2: improve resilience on busy systems
  selinux: use safe procfs API for labels
  rootfs: switch to fd-based handling of mountpoint targets
  libct/system: use securejoin for /proc/$pid/stat
  init: use securejoin for /proc/self/setgroups
  init: write sysctls using safe procfs API
  utils: remove unneeded EnsureProcHandle
  utils: use safe procfs for /proc/self/fd loop code
  apparmor: use safe procfs API for labels
  ci: add lint to forbid the usage of os.Create
  rootfs: avoid using os.Create for new device inodes
  internal: add wrappers for securejoin.Proc*
  go.mod: update to github.com/cyphar/filepath-securejoin@v0.5.0
  console: verify /dev/pts/ptmx before use
  console: avoid trivial symlink attacks for /dev/console
  console: add fallback for pre-TIOCGPTPEER kernels
  console: use TIOCGPTPEER when allocating peer PTY
  *: switch to safer securejoin.Reopen
  internal: move utils.MkdirAllInRoot to internal/pathrs
  internal/sys: add VerifyInode helper
  internal: linux: add package doc-comment

Li Fubang (1):
  libct: align param type for mountCgroupV1/V2 functions

Kir Kolyshkin (3):
  libct: maskPaths: don't rely on ENOTDIR for mount
  libct: maskPaths: only ignore ENOENT on mount dest
  libct: add/use isDevNull, verifyDevNull

Fixes: CVE-2025-31133 GHSA-9493-h29p-rfm2
Fixes: CVE-2025-52565 GHSA-qw9x-cqr3-wc7r
Fixes: CVE-2025-52881 GHSA-cgrx-mc8f-2prm
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 20:31:25 +11:00
Aleksa Sarai b5d3280029 VERSION: back to development
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 20:08:41 +11:00
Aleksa Sarai 6c7d8ad602 VERSION: release v1.4.0-rc.3
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
v1.4.0-rc.3
2025-11-05 20:08:32 +11:00
Aleksa Sarai 12d8457f73 merge private security patches into ghsa-release-1.4.0-rc.3
Aleksa Sarai (22):
  rootfs: re-allow dangling symlinks in mount targets
  openat2: improve resilience on busy systems
  selinux: use safe procfs API for labels
  rootfs: switch to fd-based handling of mountpoint targets
  libct/system: use securejoin for /proc/$pid/stat
  init: use securejoin for /proc/self/setgroups
  init: write sysctls using safe procfs API
  utils: remove unneeded EnsureProcHandle
  utils: use safe procfs for /proc/self/fd loop code
  apparmor: use safe procfs API for labels
  ci: add lint to forbid the usage of os.Create
  rootfs: avoid using os.Create for new device inodes
  internal: add wrappers for securejoin.Proc*
  go.mod: update to github.com/cyphar/filepath-securejoin@v0.5.0
  console: verify /dev/pts/ptmx before use
  console: avoid trivial symlink attacks for /dev/console
  console: add fallback for pre-TIOCGPTPEER kernels
  console: use TIOCGPTPEER when allocating peer PTY
  *: switch to safer securejoin.Reopen
  internal: move utils.MkdirAllInRoot to internal/pathrs
  internal/sys: add VerifyInode helper
  internal: linux: add package doc-comment

Li Fubang (1):
  libct: align param type for mountCgroupV1/V2 functions

Kir Kolyshkin (3):
  libct: maskPaths: don't rely on ENOTDIR for mount
  libct: maskPaths: only ignore ENOENT on mount dest
  libct: add/use isDevNull, verifyDevNull

Fixes: CVE-2025-31133 GHSA-9493-h29p-rfm2
Fixes: CVE-2025-52565 GHSA-qw9x-cqr3-wc7r
Fixes: CVE-2025-52881 GHSA-cgrx-mc8f-2prm
Reported-by: Lei Wang <ssst0n3@gmail.com>
Reported-by: Li Fubang <lifubang@acmcoder.com>
Reported-by: Tõnis Tiigi <tonistiigi@gmail.com>
Reported-by: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 20:07:36 +11:00
Aleksa Sarai f724d6164d rootfs: re-allow dangling symlinks in mount targets
It seems there are a fair few images where dangling symlinks are used as
path components for mount targets, which pathrs-lite does not support
(and it would be difficult to fully support this in a race-free way).

This was actually meant to be blocked by commit 63c2908164 ("rootfs:
try to scope MkdirAll to stay inside the rootfs"), followed by commit
dd827f7b71 ("utils: switch to securejoin.MkdirAllHandle"). However, we
still used SecureJoin to construct mountpoint targets, which means that
dangling symlinks were "resolved" before reaching pathrs-lite.

This patch basically re-adds this hack in order to reduce the breakages
we've seen so far.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:42 +11:00
Aleksa Sarai 753884a0ff openat2: improve resilience on busy systems
Previously, we would see a ~3% failure rate when starting containers
with mounts that contain ".." (which can trigger -EAGAIN). To counteract
this, filepath-securejoin v0.5.1 includes a bump of the internal retry
limit from 32 to 128, which lowers the failure rate to 0.12%.

However, there is still a risk of spurious failure on regular systems.
In order to try to provide more resilience (while avoiding DoS attacks),
this patch also includes an additional retry loop that terminates based
on a deadline rather than retry count. The deadline is 2ms, as my
testing found that ~800us for a single pathrs operation was the longest
latency due to -EAGAIN retries, and that was an outlier compared to the
more common ~400us latencies -- so 2ms should be more than enough for
any real system.

The failure rates above were based on more 50k runs of runc with an
attack script (from libpathrs) running a rename attack on all cores of a
16-core system, which is arguably a worst-case but heavily utilised
servers could likely approach similar results.

Tested-by: Phil Estes <estesp@gmail.com>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:42 +11:00
Aleksa Sarai d2c174c67f selinux: use safe procfs API for labels
Due to the sensitive nature of these fixes, it was not possible to
submit these upstream and vendor the upstream library. Instead, this
patch uses a fork of github.com/opencontainers/selinux, branched at
commit opencontainers/selinux@879a755db5.

In order to permit downstreams to build with this patched version, a
snapshot of the forked version has been included in
internal/third_party/selinux. Note that since we use "go mod vendor",
the patched code is usable even without being "go get"-able. Once the
embargo for this issue is lifted we can submit the patches upstream and
switch back to a proper upstream go.mod entry.

Also, this requires us to temporarily disable the CI job we have that
disallows "replace" directives.

Fixes: GHSA-cgrx-mc8f-2prm CVE-2025-52881
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:41 +11:00
Aleksa Sarai 5debde388e rootfs: switch to fd-based handling of mountpoint targets
An attacker could race with us during mount configuration in order to
trick us into mounting over an unexpected path. This would bypass
checkProcMount() and would allow for security profiles to be left
unapplied by mounting over /proc/self/attr/... (or even more serious
outcomes such as killing the entire system by tricking runc into writing
strings to /proc/sysrq-trigger).

This is a larger issue with our current mount infrastructure, and the
ideal solution would be to rewrite it all to be fd-based (which would
also allow us to support the "new" mount API, which also avoids a bunch
of other issues with mount(8)). However, such a rewrite is not really
workable as a security fix, so this patch is a bit of a compromise
approach to fix the issue while also moving us a bit towards that
eventual end-goal.

The core issue in CVE-2025-52881 is that we currently use the (insecure)
SecureJoin to re-resolve mountpoint target paths multiple times during
mounting. Rather than generating a string from createMountpoint(), we
instead open an *os.File handle to the target mountpoint directly and
then operate on that handle. This will make it easier to remove
utils.WithProcfd() and rework mountViaFds() in the future.

The only real issue we need to work around is that we need to re-open
the mount target after doing the mount in order to get a handle to the
mountpoint -- pathrs.Reopen() doesn't work in this case (it just
re-opens the inode under the mountpoint) so we need to do a naive
re-open using the full path. Note that if we used move_mount(2) this
wouldn't be a problem because we would have a handle to the mountpoint
itself.

Note that this is still somewhat of a temporary solution -- ideally
mountViaFds would use *os.File directly to let us avoid some other
issues with using bare /proc/... paths, as well as also letting us more
easily use the new mount API on modern kernels.

Fixes: GHSA-cgrx-mc8f-2prm CVE-2025-52881
Co-developed-by: lifubang <lifubang@acmcoder.com>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:41 +11:00
lifubang 34e0b13f3f libct: align param type for mountCgroupV1/V2 functions
Signed-off-by: lifubang <lifubang@acmcoder.com>
2025-11-05 19:12:41 +11:00
Aleksa Sarai 76aa4616f5 libct/system: use securejoin for /proc/$pid/stat
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:41 +11:00
Aleksa Sarai 283adf7371 init: use securejoin for /proc/self/setgroups
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:41 +11:00
Aleksa Sarai db63540241 init: write sysctls using safe procfs API
sysctls could in principle also be used as a write gadget for arbitrary
procfs files. As this requires getting a non-subset=pid /proc handle we
amortise this by only allocating a single procfs handle for all sysctl
writes.

Fixes: GHSA-cgrx-mc8f-2prm CVE-2025-52881
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:40 +11:00
Aleksa Sarai 30d045fef3 utils: remove unneeded EnsureProcHandle
All of the callers of EnsureProcHandle now use filepath-securejoin's
ProcThreadSelf to get a file handle, which has much stricter
verification to avoid procfs attacks than EnsureProcHandle's very
simplistic filesystem type check.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:40 +11:00
Aleksa Sarai 38c6daaeee utils: use safe procfs for /proc/self/fd loop code
From a safety perspective this might not be strictly required, but it
paves the way for us to remove utils.ProcThreadSelf.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:40 +11:00
Aleksa Sarai 43001471df apparmor: use safe procfs API for labels
EnsureProcHandle only protects us against a tmpfs mount, but the risk of
a procfs path being used (such as /proc/self/sched) has been known for a
while. Now that filepath-securejoin has a reasonably safe procfs API,
switch to it.

Fixes: GHSA-cgrx-mc8f-2prm CVE-2025-52881
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:40 +11:00
Aleksa Sarai 29e1e181d1 ci: add lint to forbid the usage of os.Create
os.Create is shorthand for open(O_CREAT|O_TRUNC) *without* O_EXCL, which
is incredibly unsafe for us to do when interacting with a container
rootfs (especially before pivot_root) as an attacker could swap the
target path with a symlink that points to the host filesystem, causing
us to delete the contents of or create host files.

We did have a similar bug in CVE-2024-45310, but in that case we
(luckily) didn't have O_TRUNC set which avoided the worst possible case.
However, os.Create does set O_TRUNC and we were using it in scenarios
that may have been exploitable.

Because of how easy it us for us to accidentally introduce this kind of
bug, we should simply not allow the usage of os.Create in our entire
codebase.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:40 +11:00
Aleksa Sarai fb875cb9bc rootfs: avoid using os.Create for new device inodes
If an attacker were to make the target of a device inode creation be a
symlink to some host path, os.Create would happily truncate the target
which could lead to all sorts of issues. This exploit is probably not as
exploitable because device inodes are usually only bind-mounted for
rootless containers, which cannot overwrite important host files (though
user files would still be up for grabs).

The regular inode creation logic could also theoretically be tricked
into changing the access mode and ownership of host files if the
newly-created device inode was swapped with a symlink to a host path.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:39 +11:00
Aleksa Sarai aa466450ae internal: add wrappers for securejoin.Proc*
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:39 +11:00
Aleksa Sarai 856848696e go.mod: update to github.com/cyphar/filepath-securejoin@v0.5.0
In order to avoid lint errors due to the deprecation of the top-level
securejoin methods ported from libpathrs, we need to adjust
internal/pathrs to use the new pathrs-lite subpackage instead.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2025-11-05 19:12:39 +11:00