mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-10 21:53:57 +08:00
Merge pull request #5167 from cyphar/1.4-libpathrs-cherry-pick
[1.4] *: libpathrs cherry-picks
This commit is contained in:
@@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased 1.4.z]
|
||||
|
||||
### Changed ###
|
||||
- Previously we made an attempt to make our `runc.armhf` release binaries work
|
||||
with ARMv6 (which would allow runc to work on the original Raspberry Pi).
|
||||
Unfortunately, this has effectively always been broken (because we
|
||||
cross-compile `libseccomp` within a Debian container and statically link to
|
||||
it) and so we are now officially matching [the Debian definition of `armhf`][debian-armhf]
|
||||
(that is, ARMv7). (#5103)
|
||||
|
||||
[debian-armhf]: https://wiki.debian.org/ArmHardFloatPort
|
||||
|
||||
## [1.4.0] - 2025-11-27
|
||||
|
||||
> 路漫漫其修远兮,吾将上下而求索!
|
||||
|
||||
+11
-7
@@ -2,9 +2,9 @@ ARG GO_VERSION=1.25
|
||||
ARG BATS_VERSION=v1.12.0
|
||||
ARG LIBSECCOMP_VERSION=2.6.0
|
||||
|
||||
FROM golang:${GO_VERSION}-bookworm
|
||||
FROM golang:${GO_VERSION}-trixie
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG CRIU_REPO=https://download.opensuse.org/repositories/devel:/tools:/criu/Debian_12
|
||||
ARG CRIU_REPO=https://download.opensuse.org/repositories/devel:/tools:/criu/Debian_13
|
||||
|
||||
RUN KEYFILE=/usr/share/keyrings/criu-repo-keyring.gpg; \
|
||||
wget -nv $CRIU_REPO/Release.key -O- | gpg --dearmor > "$KEYFILE" \
|
||||
@@ -54,14 +54,18 @@ RUN cd /tmp \
|
||||
&& ./install.sh /usr/local \
|
||||
&& rm -rf /tmp/bats-core
|
||||
|
||||
ARG RELEASE_ARCHES="386 amd64 arm64 armel armhf ppc64le riscv64 s390x"
|
||||
ENV DYLIB_DIR=/opt/runc-dylibs
|
||||
|
||||
# install libseccomp
|
||||
ARG LIBSECCOMP_VERSION
|
||||
COPY script/seccomp.sh script/lib.sh /tmp/script/
|
||||
RUN mkdir -p /opt/libseccomp \
|
||||
&& /tmp/script/seccomp.sh "$LIBSECCOMP_VERSION" /opt/libseccomp 386 amd64 arm64 armel armhf ppc64le riscv64 s390x
|
||||
COPY script/build-seccomp.sh script/lib.sh /tmp/script/
|
||||
RUN mkdir -p $DYLIB_DIR \
|
||||
&& /tmp/script/build-seccomp.sh "$LIBSECCOMP_VERSION" $DYLIB_DIR $RELEASE_ARCHES
|
||||
ENV LIBSECCOMP_VERSION=$LIBSECCOMP_VERSION
|
||||
ENV LD_LIBRARY_PATH=/opt/libseccomp/lib
|
||||
ENV PKG_CONFIG_PATH=/opt/libseccomp/lib/pkgconfig
|
||||
|
||||
ENV LD_LIBRARY_PATH=$DYLIB_DIR/lib
|
||||
ENV PKG_CONFIG_PATH=$DYLIB_DIR/lib/pkgconfig
|
||||
|
||||
# Prevent the "fatal: detected dubious ownership in repository" git complain during build.
|
||||
RUN git config --global --add safe.directory /go/src/github.com/opencontainers/runc
|
||||
|
||||
@@ -112,6 +112,7 @@ make EXTRA_BUILDTAGS="runc_nocriu"
|
||||
| Build Tag | Feature | Enabled by Default | Dependencies |
|
||||
|---------------|---------------------------------------|--------------------|---------------------|
|
||||
| `seccomp` | Syscall filtering using `libseccomp`. | yes | `libseccomp` |
|
||||
| `libpathrs` | Use [`libpathrs`][] for path safety. | no | [`libpathrs`][] |
|
||||
| `runc_nocriu` | **Disables** runc checkpoint/restore. | no | `criu` |
|
||||
|
||||
The following build tags were used earlier, but are now obsoleted:
|
||||
@@ -120,6 +121,8 @@ The following build tags were used earlier, but are now obsoleted:
|
||||
- **apparmor** (since runc v1.0.0-rc93 the feature is always enabled)
|
||||
- **selinux** (since runc v1.0.0-rc93 the feature is always enabled)
|
||||
|
||||
[`libpathrs`]: https://github.com/cyphar/libpathrs
|
||||
|
||||
### Running the test suite
|
||||
|
||||
`runc` currently supports running its test suite via Docker.
|
||||
|
||||
@@ -28,7 +28,7 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
cyphar.com/go-pathrs v0.2.1 // indirect
|
||||
cyphar.com/go-pathrs v0.2.4 // indirect
|
||||
github.com/cilium/ebpf v0.17.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8=
|
||||
cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=
|
||||
cyphar.com/go-pathrs v0.2.4 h1:iD/mge36swa1UFKdINkr1Frkpp6wZsy3YYEildj9cLY=
|
||||
cyphar.com/go-pathrs v0.2.4/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/checkpoint-restore/go-criu/v7 v7.2.0 h1:qGiWA4App1gGlEfIJ68WR9jbezV9J7yZdjzglezcqKo=
|
||||
github.com/checkpoint-restore/go-criu/v7 v7.2.0/go.mod h1:u0LCWLg0w4yqqu14aXhiB4YD3a1qd8EcCEg7vda5dwo=
|
||||
|
||||
@@ -65,7 +65,7 @@ function build_libseccomp() {
|
||||
}
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "Usage: seccomp.sh <version> <dest-dir> [<extra-arch> ...]" >&2
|
||||
echo "Usage: $0 <version> <dest-dir> [<extra-arch> ...]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
+1
-10
@@ -48,16 +48,7 @@ function set_cross_vars() {
|
||||
armhf)
|
||||
HOST=arm-${PLATFORM}eabihf
|
||||
GOARCH=arm
|
||||
# "armhf" means ARMv7 for Debian, ARMv6 for Raspbian.
|
||||
# ARMv6 is chosen here for compatibility.
|
||||
#
|
||||
# https://wiki.debian.org/RaspberryPi
|
||||
#
|
||||
# > Raspberry Pi OS builds a single image for all of the Raspberry families,
|
||||
# > so you will get an armhf 32-bit, hard floating-point system, but built
|
||||
# > for the ARMv6 ISA (with VFP2), unlike Debian's ARMv7 ISA (with VFP3)
|
||||
# > port.
|
||||
GOARM=6
|
||||
GOARM=7
|
||||
;;
|
||||
ppc64le)
|
||||
HOST=powerpc64le-${PLATFORM}
|
||||
|
||||
+9
-14
@@ -40,14 +40,14 @@ function build_project() {
|
||||
shift
|
||||
local arches=("$@")
|
||||
|
||||
# Assume that if /opt/libseccomp exists, then we are run
|
||||
# via Dockerfile, and seccomp is already built.
|
||||
local seccompdir=/opt/libseccomp temp_dir
|
||||
if [ ! -d "$seccompdir" ]; then
|
||||
temp_dir="$(mktemp -d)"
|
||||
seccompdir="$temp_dir"
|
||||
# Assume that if /opt/runc-dylibs exists, then we are running via
|
||||
# Dockerfile, and thus seccomp is already built. Otherwise, build it now.
|
||||
local dylibdir=/opt/runc-dylibs
|
||||
if ! [ -d "$dylibdir" ]; then
|
||||
trap 'rm -rf "$dylibdir"' EXIT
|
||||
dylibdir="$(mktemp -d)"
|
||||
# Download and build libseccomp.
|
||||
"$root/script/seccomp.sh" "$LIBSECCOMP_VERSION" "$seccompdir" "${arches[@]}"
|
||||
"$root/script/build-seccomp.sh" "$LIBSECCOMP_VERSION" "$dylibdir" "${arches[@]}"
|
||||
fi
|
||||
|
||||
# For reproducible builds, add these to EXTRA_LDFLAGS:
|
||||
@@ -70,7 +70,7 @@ function build_project() {
|
||||
CFLAGS="$original_cflags"
|
||||
set_cross_vars "$arch"
|
||||
make -C "$root" \
|
||||
PKG_CONFIG_PATH="$seccompdir/$arch/lib/pkgconfig" \
|
||||
PKG_CONFIG_PATH="$dylibdir/$arch/lib/pkgconfig" \
|
||||
"${make_args[@]}"
|
||||
"$STRIP" "$root/$project"
|
||||
mv "$root/$project" "$builddir/$project.$arch"
|
||||
@@ -85,12 +85,7 @@ function build_project() {
|
||||
fi
|
||||
|
||||
# Copy libseccomp source tarball.
|
||||
cp "$seccompdir"/src/* "$builddir"
|
||||
|
||||
# Clean up.
|
||||
if [ -n "$tempdir" ]; then
|
||||
rm -rf "$tempdir"
|
||||
fi
|
||||
cp "$dylibdir"/src/* "$builddir"
|
||||
}
|
||||
|
||||
# End of the easy-to-configure portion.
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
#
|
||||
# libpathrs: safe path resolution on Linux
|
||||
# Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
||||
# Copyright (C) 2019-2025 SUSE LLC
|
||||
# Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
/*
|
||||
* libpathrs: safe path resolution on Linux
|
||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
||||
* Copyright (C) 2019-2025 SUSE LLC
|
||||
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|
||||
+3
-7
@@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
/*
|
||||
* libpathrs: safe path resolution on Linux
|
||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
||||
* Copyright (C) 2019-2025 SUSE LLC
|
||||
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -30,11 +30,9 @@ import (
|
||||
// you can try to use [Root.Open] or [Root.OpenFile].
|
||||
//
|
||||
// It is critical that perform all relevant operations through this [Handle]
|
||||
// (rather than fetching the file descriptor yourself with [Handle.IntoRaw]),
|
||||
// (rather than fetching the underlying [os.File] yourself with [Handle.IntoFile]),
|
||||
// because the security properties of libpathrs depend on users doing all
|
||||
// relevant filesystem operations through libpathrs.
|
||||
//
|
||||
// [os.File]: https://pkg.go.dev/os#File
|
||||
type Handle struct {
|
||||
inner *os.File
|
||||
}
|
||||
@@ -43,7 +41,7 @@ type Handle struct {
|
||||
// handle will be copied by this method, so the original handle should still be
|
||||
// freed by the caller.
|
||||
//
|
||||
// This is effectively the inverse operation of [Handle.IntoRaw], and is used
|
||||
// This is effectively the inverse operation of [Handle.IntoFile], and is used
|
||||
// for "deserialising" pathrs root handles.
|
||||
func HandleFromFile(file *os.File) (*Handle, error) {
|
||||
newFile, err := fdutils.DupFile(file)
|
||||
@@ -92,8 +90,6 @@ func (h *Handle) OpenFile(flags int) (*os.File, error) {
|
||||
// calling [Handle.Close] will also close any copies of the returned [os.File].
|
||||
// If you want to get an independent copy, use [Handle.Clone] followed by
|
||||
// [Handle.IntoFile] on the cloned [Handle].
|
||||
//
|
||||
// [os.File]: https://pkg.go.dev/os#File
|
||||
func (h *Handle) IntoFile() *os.File {
|
||||
// TODO: Figure out if we really don't want to make a copy.
|
||||
// TODO: We almost certainly want to clear r.inner here, but we can't do
|
||||
|
||||
+1
-1
@@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
/*
|
||||
* libpathrs: safe path resolution on Linux
|
||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
||||
* Copyright (C) 2019-2025 SUSE LLC
|
||||
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|
||||
+1
-1
@@ -5,8 +5,8 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
/*
|
||||
* libpathrs: safe path resolution on Linux
|
||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
||||
* Copyright (C) 2019-2025 SUSE LLC
|
||||
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|
||||
+3
-3
@@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
/*
|
||||
* libpathrs: safe path resolution on Linux
|
||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
||||
* Copyright (C) 2019-2025 SUSE LLC
|
||||
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -100,7 +100,7 @@ func InRootReadlink(rootFd uintptr, path string) (string, error) {
|
||||
size := 128
|
||||
for {
|
||||
linkBuf := make([]byte, size)
|
||||
n := C.pathrs_inroot_readlink(C.int(rootFd), cPath, C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf)))
|
||||
n := C.pathrs_inroot_readlink(C.int(rootFd), cPath, C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.size_t(len(linkBuf)))
|
||||
switch {
|
||||
case int(n) < C.__PATHRS_MAX_ERR_VALUE:
|
||||
return "", fetchError(n)
|
||||
@@ -301,7 +301,7 @@ func ProcReadlinkat(procRootFd int, base ProcBase, path string) (string, error)
|
||||
linkBuf := make([]byte, size)
|
||||
n := C.pathrs_proc_readlinkat(
|
||||
C.int(procRootFd), cBase, cPath,
|
||||
C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf)))
|
||||
C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.size_t(len(linkBuf)))
|
||||
switch {
|
||||
case int(n) < C.__PATHRS_MAX_ERR_VALUE:
|
||||
return "", fetchError(n)
|
||||
|
||||
+4
-11
@@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
/*
|
||||
* libpathrs: safe path resolution on Linux
|
||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
||||
* Copyright (C) 2019-2025 SUSE LLC
|
||||
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -56,16 +56,15 @@ var (
|
||||
// *before* you call wait(2)or any equivalent method that could reap
|
||||
// zombies).
|
||||
func ProcPid(pid int) ProcBase {
|
||||
if pid < 0 || pid >= 1<<31 {
|
||||
if pid < 0 || uint64(pid) >= 1<<31 {
|
||||
panic("invalid ProcBasePid value") // TODO: should this be an error?
|
||||
}
|
||||
return ProcBase{inner: libpathrs.ProcPid(uint32(pid))}
|
||||
pid32 := uint32(pid) //nolint:gosec // G115 false positive <https://github.com/securego/gosec/issues/1212>
|
||||
return ProcBase{inner: libpathrs.ProcPid(pid32)}
|
||||
}
|
||||
|
||||
// ThreadCloser is a callback that needs to be called when you are done
|
||||
// operating on an [os.File] fetched using [Handle.OpenThreadSelf].
|
||||
//
|
||||
// [os.File]: https://pkg.go.dev/os#File
|
||||
type ThreadCloser func()
|
||||
|
||||
// Handle is a wrapper around an *os.File handle to "/proc", which can be
|
||||
@@ -181,8 +180,6 @@ func (proc *Handle) OpenRoot(path string, flags int) (*os.File, error) {
|
||||
// Unlike [Handle.OpenThreadSelf], this method does not involve locking
|
||||
// the goroutine to the current OS thread and so is simpler to use and
|
||||
// theoretically has slightly less overhead.
|
||||
//
|
||||
// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread
|
||||
func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) {
|
||||
file, closer, err := proc.open(ProcSelf, path, flags)
|
||||
if closer != nil {
|
||||
@@ -228,10 +225,6 @@ func (proc *Handle) OpenPid(pid int, path string, flags int) (*os.File, error) {
|
||||
// callback MUST be called AFTER you have finished using the returned
|
||||
// [os.File]. This callback is completely separate to [os.File.Close], so it
|
||||
// must be called regardless of how you close the handle.
|
||||
//
|
||||
// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread
|
||||
// [os.File]: https://pkg.go.dev/os#File
|
||||
// [os.File.Close]: https://pkg.go.dev/os#File.Close
|
||||
func (proc *Handle) OpenThreadSelf(path string, flags int) (*os.File, ThreadCloser, error) {
|
||||
return proc.open(ProcThreadSelf, path, flags)
|
||||
}
|
||||
|
||||
+2
-28
@@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
/*
|
||||
* libpathrs: safe path resolution on Linux
|
||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
||||
* Copyright (C) 2019-2025 SUSE LLC
|
||||
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -54,8 +54,6 @@ func OpenRoot(path string) (*Root, error) {
|
||||
// still be closed by the caller.
|
||||
//
|
||||
// This is effectively the inverse operation of [Root.IntoFile].
|
||||
//
|
||||
// [os.File]: https://pkg.go.dev/os#File
|
||||
func RootFromFile(file *os.File) (*Root, error) {
|
||||
newFile, err := fdutils.DupFile(file)
|
||||
if err != nil {
|
||||
@@ -109,8 +107,6 @@ func (r *Root) ResolveNoFollow(path string) (*Handle, error) {
|
||||
// ergonomic to use.
|
||||
//
|
||||
// This is effectively equivalent to [os.Open].
|
||||
//
|
||||
// [os.Open]: https://pkg.go.dev/os#Open
|
||||
func (r *Root) Open(path string) (*os.File, error) {
|
||||
return r.OpenFile(path, os.O_RDONLY)
|
||||
}
|
||||
@@ -127,8 +123,6 @@ func (r *Root) Open(path string) (*os.File, error) {
|
||||
//
|
||||
// This is effectively equivalent to [os.OpenFile], except that os.O_CREAT is
|
||||
// not supported.
|
||||
//
|
||||
// [os.OpenFile]: https://pkg.go.dev/os#OpenFile
|
||||
func (r *Root) OpenFile(path string, flags int) (*os.File, error) {
|
||||
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) {
|
||||
fd, err := libpathrs.InRootOpen(rootFd, path, flags)
|
||||
@@ -145,8 +139,6 @@ func (r *Root) OpenFile(path string, flags int) (*os.File, error) {
|
||||
//
|
||||
// Unlike [os.Create], if the file already exists an error is created rather
|
||||
// than the file being opened and truncated.
|
||||
//
|
||||
// [os.Create]: https://pkg.go.dev/os#Create
|
||||
func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error) {
|
||||
unixMode, err := toUnixMode(mode, false)
|
||||
if err != nil {
|
||||
@@ -194,8 +186,6 @@ func (r *Root) RemoveFile(path string) error {
|
||||
// directory tree.
|
||||
//
|
||||
// This is effectively equivalent to [os.Remove].
|
||||
//
|
||||
// [os.Remove]: https://pkg.go.dev/os#Remove
|
||||
func (r *Root) Remove(path string) error {
|
||||
// In order to match os.Remove's implementation we need to also do both
|
||||
// syscalls unconditionally and adjust the error based on whether
|
||||
@@ -219,8 +209,6 @@ func (r *Root) Remove(path string) error {
|
||||
// RemoveAll recursively deletes a path and all of its children.
|
||||
//
|
||||
// This is effectively equivalent to [os.RemoveAll].
|
||||
//
|
||||
// [os.RemoveAll]: https://pkg.go.dev/os#RemoveAll
|
||||
func (r *Root) RemoveAll(path string) error {
|
||||
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
|
||||
err := libpathrs.InRootRemoveAll(rootFd, path)
|
||||
@@ -233,8 +221,6 @@ func (r *Root) RemoveAll(path string) error {
|
||||
// mode is used for the new directory (the process's umask applies).
|
||||
//
|
||||
// This is effectively equivalent to [os.Mkdir].
|
||||
//
|
||||
// [os.Mkdir]: https://pkg.go.dev/os#Mkdir
|
||||
func (r *Root) Mkdir(path string, mode os.FileMode) error {
|
||||
unixMode, err := toUnixMode(mode, false)
|
||||
if err != nil {
|
||||
@@ -253,8 +239,6 @@ func (r *Root) Mkdir(path string, mode os.FileMode) error {
|
||||
// directories created by this function (the process's umask applies).
|
||||
//
|
||||
// This is effectively equivalent to [os.MkdirAll].
|
||||
//
|
||||
// [os.MkdirAll]: https://pkg.go.dev/os#MkdirAll
|
||||
func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) {
|
||||
unixMode, err := toUnixMode(mode, false)
|
||||
if err != nil {
|
||||
@@ -278,9 +262,7 @@ func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) {
|
||||
// directory tree. The provided mode is used for the new directory (the
|
||||
// process's umask applies).
|
||||
//
|
||||
// This is effectively equivalent to [unix.Mknod].
|
||||
//
|
||||
// [unix.Mknod]: https://pkg.go.dev/golang.org/x/sys/unix#Mknod
|
||||
// This is effectively equivalent to [golang.org/x/sys/unix.Mknod].
|
||||
func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error {
|
||||
unixMode, err := toUnixMode(mode, true)
|
||||
if err != nil {
|
||||
@@ -298,8 +280,6 @@ func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error {
|
||||
// created at path and is a link to target.
|
||||
//
|
||||
// This is effectively equivalent to [os.Symlink].
|
||||
//
|
||||
// [os.Symlink]: https://pkg.go.dev/os#Symlink
|
||||
func (r *Root) Symlink(path, target string) error {
|
||||
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
|
||||
err := libpathrs.InRootSymlink(rootFd, path, target)
|
||||
@@ -314,8 +294,6 @@ func (r *Root) Symlink(path, target string) error {
|
||||
// host).
|
||||
//
|
||||
// This is effectively equivalent to [os.Link].
|
||||
//
|
||||
// [os.Link]: https://pkg.go.dev/os#Link
|
||||
func (r *Root) Hardlink(path, target string) error {
|
||||
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
|
||||
err := libpathrs.InRootHardlink(rootFd, path, target)
|
||||
@@ -327,8 +305,6 @@ func (r *Root) Hardlink(path, target string) error {
|
||||
// Readlink returns the target of a symlink with a [Root]'s directory tree.
|
||||
//
|
||||
// This is effectively equivalent to [os.Readlink].
|
||||
//
|
||||
// [os.Readlink]: https://pkg.go.dev/os#Readlink
|
||||
func (r *Root) Readlink(path string) (string, error) {
|
||||
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (string, error) {
|
||||
return libpathrs.InRootReadlink(rootFd, path)
|
||||
@@ -345,8 +321,6 @@ func (r *Root) Readlink(path string) (string, error) {
|
||||
// calling [Root.Close] will also close any copies of the returned [os.File].
|
||||
// If you want to get an independent copy, use [Root.Clone] followed by
|
||||
// [Root.IntoFile] on the cloned [Root].
|
||||
//
|
||||
// [os.File]: https://pkg.go.dev/os#File
|
||||
func (r *Root) IntoFile() *os.File {
|
||||
// TODO: Figure out if we really don't want to make a copy.
|
||||
// TODO: We almost certainly want to clear r.inner here, but we can't do
|
||||
|
||||
+1
-1
@@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
/*
|
||||
* libpathrs: safe path resolution on Linux
|
||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
||||
* Copyright (C) 2019-2025 SUSE LLC
|
||||
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# cyphar.com/go-pathrs v0.2.1
|
||||
# cyphar.com/go-pathrs v0.2.4
|
||||
## explicit; go 1.18
|
||||
cyphar.com/go-pathrs
|
||||
cyphar.com/go-pathrs/internal/fdutils
|
||||
|
||||
Reference in New Issue
Block a user