mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
merge #5103 into opencontainers/runc:main
Aleksa Sarai (11): gha: test both with and without libpathrs build: enable libpathrs by default ci: build and install libpathrs build: enable builds with libpathrs deps: update to cyphar.com/go-pathrs@v0.2.4 README: document libpathrs build tag script: seccomp.sh -> build-seccomp.sh build: rename /opt/libseccomp cdylib directory build: treat armhf as ARMv7 dockerfile: switch to Debian 13 integration: output debug information in fd leak test LGTMs: rata kolyshkin AkihiroSuda
This commit is contained in:
+5
-1
@@ -13,7 +13,8 @@ task:
|
|||||||
CIRRUS_WORKING_DIR: /home/runc
|
CIRRUS_WORKING_DIR: /home/runc
|
||||||
GO_VER_PREFIX: "1.25."
|
GO_VER_PREFIX: "1.25."
|
||||||
BATS_VERSION: "v1.12.0"
|
BATS_VERSION: "v1.12.0"
|
||||||
RPMS: gcc git-core iptables jq glibc-static libseccomp-devel make criu fuse-sshfs container-selinux policycoreutils
|
LIBPATHRS_VERSION: "0.2.4"
|
||||||
|
RPMS: gcc git-core iptables jq glibc-static libseccomp-devel make criu fuse-sshfs container-selinux policycoreutils cargo lld wget
|
||||||
# yamllint disable rule:key-duplicates
|
# yamllint disable rule:key-duplicates
|
||||||
matrix:
|
matrix:
|
||||||
- DISTRO: almalinux-8
|
- DISTRO: almalinux-8
|
||||||
@@ -63,6 +64,9 @@ task:
|
|||||||
dnf -y install criu
|
dnf -y install criu
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Install libpathrs.
|
||||||
|
/home/runc/script/build-libpathrs.sh "$LIBPATHRS_VERSION" /usr
|
||||||
|
|
||||||
# Install Go.
|
# Install Go.
|
||||||
URL_PREFIX="https://go.dev/dl/"
|
URL_PREFIX="https://go.dev/dl/"
|
||||||
# Find out the latest minor release URL.
|
# Find out the latest minor release URL.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
LIBPATHRS_VERSION: "0.2.4"
|
||||||
# Don't ignore C warnings. Note that the output of "go env CGO_CFLAGS" by default is "-g -O2", so we keep them.
|
# Don't ignore C warnings. Note that the output of "go env CGO_CFLAGS" by default is "-g -O2", so we keep them.
|
||||||
CGO_CFLAGS: -g -O2 -Werror
|
CGO_CFLAGS: -g -O2 -Werror
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-24.04, ubuntu-24.04-arm]
|
os: [ubuntu-24.04, ubuntu-24.04-arm]
|
||||||
go-version: [1.24.x, 1.25.x, 1.26.x]
|
go-version: [1.24.x, 1.25.x, 1.26.x]
|
||||||
|
libpathrs: ["libpathrs", ""]
|
||||||
rootless: ["rootless", ""]
|
rootless: ["rootless", ""]
|
||||||
race: ["-race", ""]
|
race: ["-race", ""]
|
||||||
criu: ["", "criu-dev"]
|
criu: ["", "criu-dev"]
|
||||||
@@ -75,7 +77,19 @@ jobs:
|
|||||||
- name: install deps
|
- name: install deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt -y install libseccomp-dev sshfs uidmap
|
sudo apt -y install libseccomp-dev sshfs uidmap lld
|
||||||
|
|
||||||
|
- name: install libpathrs ${{ env.LIBPATHRS_VERSION }}
|
||||||
|
if: ${{ matrix.libpathrs != '' }}
|
||||||
|
run: |
|
||||||
|
sudo -E PATH="$PATH" ./script/build-libpathrs.sh "$LIBPATHRS_VERSION" /usr
|
||||||
|
|
||||||
|
- name: configure custom BUILDTAGS
|
||||||
|
if: ${{ matrix.libpathrs == '' }}
|
||||||
|
run: |-
|
||||||
|
# Strip out libpathrs from the default buildtags.
|
||||||
|
CUSTOM_BUILDTAGS="$(make -pn | sed -En '/^BUILDTAGS :?=/ { s/.*=// ; s/\blibpathrs\b//p }')"
|
||||||
|
echo "CUSTOM_BUILDTAGS=$CUSTOM_BUILDTAGS" >>"$GITHUB_ENV"
|
||||||
|
|
||||||
- name: install CRIU
|
- name: install CRIU
|
||||||
if: ${{ matrix.criu == '' }}
|
if: ${{ matrix.criu == '' }}
|
||||||
@@ -107,7 +121,11 @@ jobs:
|
|||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: build
|
- name: build
|
||||||
run: sudo -E PATH="$PATH" make EXTRA_FLAGS="${{ matrix.race }}" all
|
run: |
|
||||||
|
sudo -E PATH="$PATH" make \
|
||||||
|
${CUSTOM_BUILDTAGS:+BUILDTAGS="$CUSTOM_BUILDTAGS"} \
|
||||||
|
EXTRA_FLAGS="${{ matrix.race }}" \
|
||||||
|
all
|
||||||
|
|
||||||
- name: Setup Bats and bats libs
|
- name: Setup Bats and bats libs
|
||||||
uses: bats-core/bats-action@4.0.0
|
uses: bats-core/bats-action@4.0.0
|
||||||
@@ -126,7 +144,7 @@ jobs:
|
|||||||
|
|
||||||
- name: unit test
|
- name: unit test
|
||||||
if: matrix.rootless != 'rootless'
|
if: matrix.rootless != 'rootless'
|
||||||
run: sudo -E PATH="$PATH" -- make TESTFLAGS="${{ matrix.race }}" localunittest
|
run: sudo -E PATH="$PATH" -- make ${CUSTOM_BUILDTAGS:+BUILDTAGS="$CUSTOM_BUILDTAGS"} TESTFLAGS="${{ matrix.race }}" localunittest
|
||||||
|
|
||||||
- name: add rootless user
|
- name: add rootless user
|
||||||
if: matrix.rootless == 'rootless'
|
if: matrix.rootless == 'rootless'
|
||||||
@@ -136,7 +154,7 @@ jobs:
|
|||||||
|
|
||||||
- name: integration test (fs driver)
|
- name: integration test (fs driver)
|
||||||
continue-on-error: ${{ matrix.criu != '' }} # Don't let criu-dev errors fail CI.
|
continue-on-error: ${{ matrix.criu != '' }} # Don't let criu-dev errors fail CI.
|
||||||
run: sudo -E PATH="$PATH" script -e -c 'make local${{ matrix.rootless }}integration'
|
run: sudo -E PATH="$PATH" script -e -c 'make ${CUSTOM_BUILDTAGS:+BUILDTAGS="$CUSTOM_BUILDTAGS"} local${{ matrix.rootless }}integration'
|
||||||
|
|
||||||
- name: integration test (systemd driver)
|
- name: integration test (systemd driver)
|
||||||
continue-on-error: ${{ matrix.criu != '' }} # Don't let criu-dev errors fail CI.
|
continue-on-error: ${{ matrix.criu != '' }} # Don't let criu-dev errors fail CI.
|
||||||
@@ -147,7 +165,7 @@ jobs:
|
|||||||
printf "[Service]\nDelegate=yes\n" | sudo tee /etc/systemd/system/user@.service.d/delegate.conf
|
printf "[Service]\nDelegate=yes\n" | sudo tee /etc/systemd/system/user@.service.d/delegate.conf
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
# Run the tests.
|
# Run the tests.
|
||||||
sudo -E PATH="$PATH" script -e -c 'make RUNC_USE_SYSTEMD=yes local${{ matrix.rootless }}integration'
|
sudo -E PATH="$PATH" script -e -c 'make RUNC_USE_SYSTEMD=yes ${CUSTOM_BUILDTAGS:+BUILDTAGS="$CUSTOM_BUILDTAGS"} local${{ matrix.rootless }}integration'
|
||||||
|
|
||||||
# We need to continue support for 32-bit ARM.
|
# We need to continue support for 32-bit ARM.
|
||||||
# However, we do not have 32-bit ARM CI, so we use i386 for testing 32bit stuff.
|
# However, we do not have 32-bit ARM CI, so we use i386 for testing 32bit stuff.
|
||||||
@@ -170,7 +188,23 @@ jobs:
|
|||||||
sudo add-apt-repository -y ppa:criu/ppa || sudo add-apt-repository -y ppa:criu/ppa
|
sudo add-apt-repository -y ppa:criu/ppa || sudo add-apt-repository -y ppa:criu/ppa
|
||||||
# apt-add-repository runs apt update so we don't have to.
|
# apt-add-repository runs apt update so we don't have to.
|
||||||
|
|
||||||
sudo apt -qy install libseccomp-dev libseccomp-dev:i386 gcc-multilib libgcc-s1:i386 criu
|
GCC_VERSION="$(gcc -dumpversion)"
|
||||||
|
sudo apt -qy install \
|
||||||
|
lld criu \
|
||||||
|
libseccomp-dev libseccomp-dev:i386 \
|
||||||
|
libc-dev:i386 libgcc-s1:i386 libgcc-${GCC_VERSION}-dev:i386 gcc-i686-linux-gnu
|
||||||
|
|
||||||
|
# When cross-compiling, GCC 13 and earlier will look for a linker that
|
||||||
|
# is marked for cross-compilation, which the Ubuntu lld package doesn't
|
||||||
|
# provide. The solution is to create a symlink ourselves. GCC 14 fixed
|
||||||
|
# this, see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111605>.
|
||||||
|
ln -sv "$(which ld.lld)" /usr/local/bin/i686-linux-gnu-ld.lld
|
||||||
|
- run: rustup target add i686-unknown-linux-gnu
|
||||||
|
|
||||||
|
- name: install libpathrs ${{ env.LIBPATHRS_VERSION }}
|
||||||
|
run: |
|
||||||
|
sudo -E PATH="$PATH" ./script/build-libpathrs.sh "$LIBPATHRS_VERSION" /usr 386
|
||||||
|
sudo ldconfig /usr/386/lib
|
||||||
|
|
||||||
- name: install go
|
- name: install go
|
||||||
uses: actions/setup-go@v6
|
uses: actions/setup-go@v6
|
||||||
@@ -179,6 +213,9 @@ jobs:
|
|||||||
check-latest: true
|
check-latest: true
|
||||||
|
|
||||||
- name: unit test
|
- name: unit test
|
||||||
|
env:
|
||||||
|
CC: i686-linux-gnu-gcc
|
||||||
|
PKG_CONFIG_PATH: /usr/386/lib/pkgconfig
|
||||||
run: sudo -E PATH="$PATH" -- make GOARCH=386 localunittest
|
run: sudo -E PATH="$PATH" -- make GOARCH=386 localunittest
|
||||||
|
|
||||||
fedora:
|
fedora:
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ on:
|
|||||||
- release-*
|
- release-*
|
||||||
pull_request:
|
pull_request:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
env:
|
|
||||||
GO_VERSION: 1.25
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
|
env:
|
||||||
|
GO_VERSION: 1.25
|
||||||
|
LIBPATHRS_VERSION: "0.2.4"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
keyring:
|
keyring:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
@@ -85,7 +88,10 @@ jobs:
|
|||||||
- name: install deps
|
- name: install deps
|
||||||
run: |
|
run: |
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt -y install libseccomp-dev
|
sudo apt -y install libseccomp-dev lld
|
||||||
|
- name: install libpathrs ${{ env.LIBPATHRS_VERSION }}
|
||||||
|
run: |
|
||||||
|
sudo -E PATH="$PATH" ./script/build-libpathrs.sh "$LIBPATHRS_VERSION" /usr
|
||||||
- name: compile with no build tags
|
- name: compile with no build tags
|
||||||
run: make BUILDTAGS=""
|
run: make BUILDTAGS=""
|
||||||
- name: compile with runc_nocriu build tag
|
- name: compile with runc_nocriu build tag
|
||||||
|
|||||||
@@ -46,6 +46,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
particularly useful and was completely obsoleted by the changes to
|
particularly useful and was completely obsoleted by the changes to
|
||||||
`/proc/self/exe` sealing we introduced in runc [1.2.0][]. (#5141)
|
`/proc/self/exe` sealing we introduced in runc [1.2.0][]. (#5141)
|
||||||
|
|
||||||
|
### Changed ###
|
||||||
|
- Our release binaries and default build configuration now use [libpathrs][] by
|
||||||
|
default, providiung better hardening against certain kinds of attacks. Users
|
||||||
|
of runc should not see any changes as a result of this, but pacakgers will
|
||||||
|
need to adjust their packaging accordingly. runc can still be built without
|
||||||
|
libpathrs (by building without the `libpathrs` build tag), but we currently
|
||||||
|
plan to make runc 1.6 *require* libpathrs. (#5103)
|
||||||
|
- 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)
|
||||||
|
|
||||||
|
[libpathrs]: https://github.com/cyphar/libpathrs
|
||||||
|
[debian-armhf]: https://wiki.debian.org/ArmHardFloatPort
|
||||||
|
|
||||||
## [1.4.0] - 2025-11-27
|
## [1.4.0] - 2025-11-27
|
||||||
|
|
||||||
> 路漫漫其修远兮,吾将上下而求索!
|
> 路漫漫其修远兮,吾将上下而求索!
|
||||||
|
|||||||
+31
-15
@@ -1,18 +1,22 @@
|
|||||||
ARG GO_VERSION=1.25
|
ARG GO_VERSION=1.25
|
||||||
ARG BATS_VERSION=v1.12.0
|
ARG BATS_VERSION=v1.12.0
|
||||||
ARG LIBSECCOMP_VERSION=2.6.0
|
ARG LIBSECCOMP_VERSION=2.6.0
|
||||||
|
ARG LIBPATHRS_VERSION=0.2.4
|
||||||
|
|
||||||
FROM golang:${GO_VERSION}-bookworm
|
FROM golang:${GO_VERSION}-trixie
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
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; \
|
RUN KEYFILE=/usr/share/keyrings/criu-repo-keyring.gpg; \
|
||||||
wget -nv $CRIU_REPO/Release.key -O- | gpg --dearmor > "$KEYFILE" \
|
wget -nv $CRIU_REPO/Release.key -O- | gpg --dearmor > "$KEYFILE" \
|
||||||
&& echo "deb [signed-by=$KEYFILE] $CRIU_REPO/ /" > /etc/apt/sources.list.d/criu.list \
|
&& echo "deb [signed-by=$KEYFILE] $CRIU_REPO/ /" > /etc/apt/sources.list.d/criu.list \
|
||||||
&& dpkg --add-architecture i386 \
|
&& printf "%s\n" i386 armel armhf arm64 ppc64el s390x riscv64 | xargs -t -n1 -- dpkg --add-architecture \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
build-essential \
|
build-essential \
|
||||||
|
cargo \
|
||||||
|
cargo-auditable \
|
||||||
|
clang \
|
||||||
criu \
|
criu \
|
||||||
gcc \
|
gcc \
|
||||||
gcc-multilib \
|
gcc-multilib \
|
||||||
@@ -22,6 +26,7 @@ RUN KEYFILE=/usr/share/keyrings/criu-repo-keyring.gpg; \
|
|||||||
iptables \
|
iptables \
|
||||||
jq \
|
jq \
|
||||||
kmod \
|
kmod \
|
||||||
|
lld \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
python3-minimal \
|
python3-minimal \
|
||||||
sshfs \
|
sshfs \
|
||||||
@@ -29,13 +34,13 @@ RUN KEYFILE=/usr/share/keyrings/criu-repo-keyring.gpg; \
|
|||||||
uidmap \
|
uidmap \
|
||||||
iproute2 \
|
iproute2 \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
libc-dev:i386 libgcc-s1:i386 \
|
libc-dev:i386 libgcc-s1:i386 gcc-i686-linux-gnu libstd-rust-dev:i386 \
|
||||||
gcc-aarch64-linux-gnu libc-dev-arm64-cross \
|
gcc-aarch64-linux-gnu libc-dev-arm64-cross libstd-rust-dev:arm64 \
|
||||||
gcc-arm-linux-gnueabi libc-dev-armel-cross \
|
gcc-arm-linux-gnueabi libc-dev-armel-cross libstd-rust-dev:armel \
|
||||||
gcc-arm-linux-gnueabihf libc-dev-armhf-cross \
|
gcc-arm-linux-gnueabihf libc-dev-armhf-cross libstd-rust-dev:armhf \
|
||||||
gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross \
|
gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross libstd-rust-dev:ppc64el \
|
||||||
gcc-s390x-linux-gnu libc-dev-s390x-cross \
|
gcc-s390x-linux-gnu libc-dev-s390x-cross libstd-rust-dev:s390x \
|
||||||
gcc-riscv64-linux-gnu libc-dev-riscv64-cross \
|
gcc-riscv64-linux-gnu libc-dev-riscv64-cross libstd-rust-dev:riscv64 \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/cache/apt /var/lib/apt/lists/* /etc/apt/sources.list.d/*.list
|
&& rm -rf /var/cache/apt /var/lib/apt/lists/* /etc/apt/sources.list.d/*.list
|
||||||
|
|
||||||
@@ -54,14 +59,25 @@ RUN cd /tmp \
|
|||||||
&& ./install.sh /usr/local \
|
&& ./install.sh /usr/local \
|
||||||
&& rm -rf /tmp/bats-core
|
&& rm -rf /tmp/bats-core
|
||||||
|
|
||||||
|
ARG RELEASE_ARCHES="386 amd64 arm64 armel armhf ppc64le riscv64 s390x"
|
||||||
|
ENV DYLIB_DIR=/opt/runc-dylibs
|
||||||
|
|
||||||
# install libseccomp
|
# install libseccomp
|
||||||
ARG LIBSECCOMP_VERSION
|
ARG LIBSECCOMP_VERSION
|
||||||
COPY script/seccomp.sh script/lib.sh /tmp/script/
|
COPY script/build-seccomp.sh script/lib.sh /tmp/script/
|
||||||
RUN mkdir -p /opt/libseccomp \
|
RUN mkdir -p $DYLIB_DIR \
|
||||||
&& /tmp/script/seccomp.sh "$LIBSECCOMP_VERSION" /opt/libseccomp 386 amd64 arm64 armel armhf ppc64le riscv64 s390x
|
&& /tmp/script/build-seccomp.sh "$LIBSECCOMP_VERSION" $DYLIB_DIR $RELEASE_ARCHES
|
||||||
ENV LIBSECCOMP_VERSION=$LIBSECCOMP_VERSION
|
ENV LIBSECCOMP_VERSION=$LIBSECCOMP_VERSION
|
||||||
ENV LD_LIBRARY_PATH=/opt/libseccomp/lib
|
|
||||||
ENV PKG_CONFIG_PATH=/opt/libseccomp/lib/pkgconfig
|
# install libpathrs
|
||||||
|
ARG LIBPATHRS_VERSION
|
||||||
|
COPY script/build-libpathrs.sh /tmp/script/
|
||||||
|
RUN mkdir -p $DYLIB_DIR \
|
||||||
|
&& /tmp/script/build-libpathrs.sh "$LIBPATHRS_VERSION" $DYLIB_DIR $RELEASE_ARCHES
|
||||||
|
ENV LIBPATHRS_VERSION=$LIBPATHRS_VERSION
|
||||||
|
|
||||||
|
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.
|
# 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
|
RUN git config --global --add safe.directory /go/src/github.com/opencontainers/runc
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ GIT_BRANCH_CLEAN := $(shell echo $(GIT_BRANCH) | sed -e "s/[^[:alnum:]]/-/g")
|
|||||||
RUNC_IMAGE := runc_dev$(if $(GIT_BRANCH_CLEAN),:$(GIT_BRANCH_CLEAN))
|
RUNC_IMAGE := runc_dev$(if $(GIT_BRANCH_CLEAN),:$(GIT_BRANCH_CLEAN))
|
||||||
PROJECT := github.com/opencontainers/runc
|
PROJECT := github.com/opencontainers/runc
|
||||||
EXTRA_BUILDTAGS :=
|
EXTRA_BUILDTAGS :=
|
||||||
BUILDTAGS := seccomp urfave_cli_no_docs
|
BUILDTAGS := seccomp urfave_cli_no_docs libpathrs
|
||||||
BUILDTAGS += $(EXTRA_BUILDTAGS)
|
BUILDTAGS += $(EXTRA_BUILDTAGS)
|
||||||
|
|
||||||
COMMIT := $(shell git describe --dirty --long --always)
|
COMMIT := $(shell git describe --dirty --long --always)
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ make EXTRA_BUILDTAGS="runc_nocriu"
|
|||||||
| Build Tag | Feature | Enabled by Default | Dependencies |
|
| Build Tag | Feature | Enabled by Default | Dependencies |
|
||||||
|---------------|---------------------------------------|--------------------|---------------------|
|
|---------------|---------------------------------------|--------------------|---------------------|
|
||||||
| `seccomp` | Syscall filtering using `libseccomp`. | yes | `libseccomp` |
|
| `seccomp` | Syscall filtering using `libseccomp`. | yes | `libseccomp` |
|
||||||
|
| `libpathrs` | Use [`libpathrs`][] for path safety. | yes | [`libpathrs`][] |
|
||||||
| `runc_nocriu` | **Disables** runc checkpoint/restore. | no | `criu` |
|
| `runc_nocriu` | **Disables** runc checkpoint/restore. | no | `criu` |
|
||||||
|
|
||||||
The following build tags were used earlier, but are now obsoleted:
|
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)
|
- **apparmor** (since runc v1.0.0-rc93 the feature is always enabled)
|
||||||
- **selinux** (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
|
### Running the test suite
|
||||||
|
|
||||||
`runc` currently supports running its test suite via Docker.
|
`runc` currently supports running its test suite via Docker.
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
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/cilium/ebpf v0.17.3 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // 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.4 h1:iD/mge36swa1UFKdINkr1Frkpp6wZsy3YYEildj9cLY=
|
||||||
cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=
|
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/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 h1:qGiWA4App1gGlEfIJ68WR9jbezV9J7yZdjzglezcqKo=
|
||||||
github.com/checkpoint-restore/go-criu/v7 v7.2.0/go.mod h1:u0LCWLg0w4yqqu14aXhiB4YD3a1qd8EcCEg7vda5dwo=
|
github.com/checkpoint-restore/go-criu/v7 v7.2.0/go.mod h1:u0LCWLg0w4yqqu14aXhiB4YD3a1qd8EcCEg7vda5dwo=
|
||||||
|
|||||||
Executable
+151
@@ -0,0 +1,151 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright (C) 2026 Open Containers Authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
set -xEeuo pipefail
|
||||||
|
|
||||||
|
# shellcheck source=./script/lib.sh
|
||||||
|
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
||||||
|
|
||||||
|
PLATFORM="$(get_platform)"
|
||||||
|
|
||||||
|
declare -A GOARCH_TO_RUST_TARGET=(
|
||||||
|
["386"]=i686-unknown-linux-gnu
|
||||||
|
["amd64"]=x86_64-unknown-linux-gnu
|
||||||
|
["arm64"]=aarch64-unknown-linux-gnu
|
||||||
|
["armel"]=armv5te-unknown-linux-gnueabi
|
||||||
|
["armhf"]=armv7-unknown-linux-gnueabihf
|
||||||
|
["ppc64le"]=powerpc64le-unknown-linux-gnu
|
||||||
|
["s390x"]=s390x-unknown-linux-gnu
|
||||||
|
["riscv64"]=riscv64gc-unknown-linux-gnu
|
||||||
|
)
|
||||||
|
|
||||||
|
declare -A RUST_TARGET_TO_CC=(
|
||||||
|
["i686-unknown-linux-gnu"]="i686-${PLATFORM}-gcc"
|
||||||
|
["x86_64-unknown-linux-gnu"]="x86_64-${PLATFORM}-gcc"
|
||||||
|
["aarch64-unknown-linux-gnu"]="aarch64-${PLATFORM}-gcc"
|
||||||
|
["armv5te-unknown-linux-gnueabi"]="arm-${PLATFORM}eabi-gcc"
|
||||||
|
["armv7-unknown-linux-gnueabihf"]="arm-${PLATFORM}eabihf-gcc"
|
||||||
|
["powerpc64le-unknown-linux-gnu"]="powerpc64le-${PLATFORM}-gcc"
|
||||||
|
["s390x-unknown-linux-gnu"]="s390x-${PLATFORM}-gcc"
|
||||||
|
["riscv64gc-unknown-linux-gnu"]="riscv64-${PLATFORM}-gcc"
|
||||||
|
)
|
||||||
|
|
||||||
|
# sha256 checksums for libpathrs release tarballs.
|
||||||
|
declare -A LIBPATHRS_SHA256=(
|
||||||
|
["0.2.4"]=45aca68e698b844fae0cf7c459bc441519b0e7b48397caa7d3936cfc68d73f77
|
||||||
|
)
|
||||||
|
|
||||||
|
function generate_cargo_config() {
|
||||||
|
for rust_target in "${GOARCH_TO_RUST_TARGET[@]}"; do
|
||||||
|
local target_gcc="${RUST_TARGET_TO_CC[$rust_target]}"
|
||||||
|
|
||||||
|
# Based on <https://wiki.debian.org/Rust#Crosscompiling>.
|
||||||
|
cat <<-EOF
|
||||||
|
[target.$rust_target]
|
||||||
|
linker = "$target_gcc"
|
||||||
|
rustflags = ["-L", "$(rustc --print sysroot)/lib/rustlib/$rust_target/lib"]
|
||||||
|
EOF
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Due to libpathrs being MPLv2/LGPLv3 we must include its sources, so
|
||||||
|
# download, install and build against it.
|
||||||
|
# Parameters:
|
||||||
|
# $1 -- libpathrs version to download and build.
|
||||||
|
# $2 -- destination directory.
|
||||||
|
# $@ -- additional architectures to cross-compile for (optional)
|
||||||
|
function build_libpathrs() {
|
||||||
|
local ver="$1"
|
||||||
|
shift
|
||||||
|
local dest="$1"
|
||||||
|
shift
|
||||||
|
local go_arches=("$@")
|
||||||
|
local tar="libpathrs-${ver}.tar.xz"
|
||||||
|
|
||||||
|
# Download, check, and extract.
|
||||||
|
wget "https://github.com/cyphar/libpathrs/releases/download/v${ver}/${tar}"{,.asc}
|
||||||
|
sha256sum --strict --check - <<<"${LIBPATHRS_SHA256[${ver}]} *${tar}"
|
||||||
|
|
||||||
|
local srcdir
|
||||||
|
srcdir="$(mktemp -d)"
|
||||||
|
tar xf "$tar" -C "$srcdir"
|
||||||
|
pushd "$srcdir/libpathrs-$ver" || return
|
||||||
|
|
||||||
|
# Use cargo-auditable if available.
|
||||||
|
if cargo auditable --version &>/dev/null; then
|
||||||
|
export CARGO="cargo auditable"
|
||||||
|
fi
|
||||||
|
local extra_cargo_flags=("--locked")
|
||||||
|
|
||||||
|
# If we are being asked to install this in a system library directory
|
||||||
|
# (i.e., --prefix=/usr or something similar), the correct place to put
|
||||||
|
# libpathrs.so depends very strongly on the distro we are running on, and
|
||||||
|
# detecting this in a generic way is quite difficult.
|
||||||
|
#
|
||||||
|
# The simplest solution is to use a disto-packaged binary to detect where
|
||||||
|
# libc.so is installed and use the same import path, so we look at
|
||||||
|
# /proc/self/maps and parse out the parent directory of the libc.so being
|
||||||
|
# used.
|
||||||
|
local native_libdir libdir=
|
||||||
|
native_libdir="$(awk '$NF ~ /\/libc\>.*\.so/ { print $NF; }' /proc/self/maps |
|
||||||
|
sort -u | head -n1 | xargs dirname)"
|
||||||
|
if [[ "$native_libdir" == "$dest/"* ]]; then
|
||||||
|
libdir="$native_libdir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install native version for Dockerfile builds.
|
||||||
|
make \
|
||||||
|
EXTRA_CARGO_FLAGS="${extra_cargo_flags[*]}" \
|
||||||
|
release
|
||||||
|
./install.sh \
|
||||||
|
--prefix="$dest" \
|
||||||
|
--libdir="$libdir"
|
||||||
|
cargo clean
|
||||||
|
|
||||||
|
local cargo_config
|
||||||
|
cargo_config="$(mktemp --tmpdir runc-libpathrs-cargo.toml.XXXXXX)"
|
||||||
|
# shellcheck disable=SC2064 # We want to resolve the path here.
|
||||||
|
trap "rm -f '$cargo_config'" EXIT
|
||||||
|
|
||||||
|
# Only use the cross-compile config when we actually need to cross-compile.
|
||||||
|
# RedHat-based distros insist on calling their targets "$ARCH-redhat-linux"
|
||||||
|
# which breaks our above logic, but we don't ever need to cross-compile on
|
||||||
|
# RedHat distros so we can ignore this.
|
||||||
|
generate_cargo_config >"$cargo_config"
|
||||||
|
extra_cargo_flags+=("--config=$cargo_config")
|
||||||
|
|
||||||
|
for go_arch in "${go_arches[@]}"; do
|
||||||
|
local rust_target="${GOARCH_TO_RUST_TARGET[$go_arch]}"
|
||||||
|
make \
|
||||||
|
EXTRA_CARGO_FLAGS="${extra_cargo_flags[*]} --target=$rust_target" \
|
||||||
|
release
|
||||||
|
./install.sh \
|
||||||
|
--rust-target="$rust_target" \
|
||||||
|
--prefix="$dest/$go_arch"
|
||||||
|
cargo clean
|
||||||
|
done
|
||||||
|
|
||||||
|
# Place the source tarball to $dest/src.
|
||||||
|
popd || return
|
||||||
|
mkdir -p "$dest"/src
|
||||||
|
mv "$tar"{,.asc} "$dest"/src
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -lt 2 ]; then
|
||||||
|
echo "Usage: $0 <version> <dest-dir> [<extra-arch> ...]" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build_libpathrs "$@"
|
||||||
@@ -60,12 +60,12 @@ function build_libseccomp() {
|
|||||||
|
|
||||||
# Place the source tarball to $dest/src.
|
# Place the source tarball to $dest/src.
|
||||||
popd || return
|
popd || return
|
||||||
mkdir "$dest"/src
|
mkdir -p "$dest"/src
|
||||||
mv "$tar"{,.asc} "$dest"/src
|
mv "$tar"{,.asc} "$dest"/src
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ $# -lt 2 ]; then
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
+32
-26
@@ -1,41 +1,56 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# get_platform computes the platform section of target triples on this OS.
|
||||||
|
function get_platform() {
|
||||||
|
# Fedora doesn't have ID_LIKE and only has ID=fedora, so we need to
|
||||||
|
# construct a fake ID_LIKE to treat AlmaLinux and Fedora the same way.
|
||||||
|
local ID_LIKE
|
||||||
|
# shellcheck source=/etc/os-release disable=SC1091 # outside our sources
|
||||||
|
ID_LIKE="$(
|
||||||
|
source /etc/os-release
|
||||||
|
echo "${ID:-} ${ID_LIKE:-}"
|
||||||
|
)"
|
||||||
|
|
||||||
|
local PLATFORM
|
||||||
|
case "$ID_LIKE" in
|
||||||
|
*suse*)
|
||||||
|
PLATFORM=suse-linux
|
||||||
|
;;
|
||||||
|
*rhel* | *fedora* | *centos*)
|
||||||
|
PLATFORM=redhat-linux
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
PLATFORM=linux-gnu
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "$PLATFORM"
|
||||||
|
}
|
||||||
|
|
||||||
# set_cross_vars sets a few environment variables used for cross-compiling,
|
# set_cross_vars sets a few environment variables used for cross-compiling,
|
||||||
# based on the architecture specified in $1.
|
# based on the architecture specified in $1.
|
||||||
function set_cross_vars() {
|
function set_cross_vars() {
|
||||||
GOARCH="$1" # default, may be overridden below
|
GOARCH="$1" # default, may be overridden below
|
||||||
unset GOARM
|
unset GOARM
|
||||||
|
|
||||||
PLATFORM=linux-gnu
|
PLATFORM="$(get_platform)"
|
||||||
# openSUSE has a custom PLATFORM
|
[[ "$PLATFORM" == *suse* ]] && is_suse=1
|
||||||
if grep -iq "ID_LIKE=.*suse" /etc/os-release; then
|
|
||||||
PLATFORM=suse-linux
|
|
||||||
is_suse=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $1 in
|
case "$1" in
|
||||||
386)
|
386)
|
||||||
# Always use the 64-bit compiler to build the 386 binary, which works
|
# Always use the 64-bit compiler to build the 386 binary, which works
|
||||||
# for the more common cross-build method for x86 (namely, the
|
# for the more common cross-build method for x86 (namely, the
|
||||||
# equivalent of dpkg --add-architecture).
|
# equivalent of dpkg --add-architecture).
|
||||||
local cpu_type
|
local cpu_type
|
||||||
if [ -v is_suse ]; then
|
if [ -v is_suse ]; then
|
||||||
# There is no x86_64-suse-linux-gcc, so use the native one.
|
|
||||||
HOST=
|
|
||||||
cpu_type=i586
|
cpu_type=i586
|
||||||
else
|
else
|
||||||
HOST=x86_64-${PLATFORM}
|
|
||||||
cpu_type=i686
|
cpu_type=i686
|
||||||
fi
|
fi
|
||||||
|
HOST=x86_64-${PLATFORM}
|
||||||
CFLAGS="-m32 -march=$cpu_type ${CFLAGS[*]}"
|
CFLAGS="-m32 -march=$cpu_type ${CFLAGS[*]}"
|
||||||
;;
|
;;
|
||||||
amd64)
|
amd64)
|
||||||
if [ -n "${is_suse:-}" ]; then
|
HOST=x86_64-${PLATFORM}
|
||||||
# There is no x86_64-suse-linux-gcc, so use the native one.
|
|
||||||
HOST=
|
|
||||||
else
|
|
||||||
HOST=x86_64-${PLATFORM}
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
arm64)
|
arm64)
|
||||||
HOST=aarch64-${PLATFORM}
|
HOST=aarch64-${PLATFORM}
|
||||||
@@ -48,16 +63,7 @@ function set_cross_vars() {
|
|||||||
armhf)
|
armhf)
|
||||||
HOST=arm-${PLATFORM}eabihf
|
HOST=arm-${PLATFORM}eabihf
|
||||||
GOARCH=arm
|
GOARCH=arm
|
||||||
# "armhf" means ARMv7 for Debian, ARMv6 for Raspbian.
|
GOARM=7
|
||||||
# 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
|
|
||||||
;;
|
;;
|
||||||
ppc64le)
|
ppc64le)
|
||||||
HOST=powerpc64le-${PLATFORM}
|
HOST=powerpc64le-${PLATFORM}
|
||||||
|
|||||||
+13
-15
@@ -20,6 +20,7 @@ set -e
|
|||||||
# Project-specific options and functions. In *theory* you shouldn't need to
|
# Project-specific options and functions. In *theory* you shouldn't need to
|
||||||
# touch anything else in this script in order to use this elsewhere.
|
# touch anything else in this script in order to use this elsewhere.
|
||||||
: "${LIBSECCOMP_VERSION:=2.6.0}"
|
: "${LIBSECCOMP_VERSION:=2.6.0}"
|
||||||
|
: "${LIBPATHRS_VERSION:=0.2.4}"
|
||||||
project="runc"
|
project="runc"
|
||||||
root="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")/..")"
|
root="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")/..")"
|
||||||
|
|
||||||
@@ -40,14 +41,16 @@ function build_project() {
|
|||||||
shift
|
shift
|
||||||
local arches=("$@")
|
local arches=("$@")
|
||||||
|
|
||||||
# Assume that if /opt/libseccomp exists, then we are run
|
# Assume that if /opt/runc-dylibs exists, then we are running via
|
||||||
# via Dockerfile, and seccomp is already built.
|
# Dockerfile, and thus seccomp is already built. Otherwise, build it now.
|
||||||
local seccompdir=/opt/libseccomp temp_dir
|
local dylibdir=/opt/runc-dylibs
|
||||||
if [ ! -d "$seccompdir" ]; then
|
if ! [ -d "$dylibdir" ]; then
|
||||||
temp_dir="$(mktemp -d)"
|
trap 'rm -rf "$dylibdir"' EXIT
|
||||||
seccompdir="$temp_dir"
|
dylibdir="$(mktemp -d)"
|
||||||
# Download and build libseccomp.
|
# Download and build libseccomp.
|
||||||
"$root/script/seccomp.sh" "$LIBSECCOMP_VERSION" "$seccompdir" "${arches[@]}"
|
"$root/script/build-seccomp.sh" "$LIBSECCOMP_VERSION" "$dylibdir" "${arches[@]}"
|
||||||
|
# Download and build libpathrs.
|
||||||
|
"$root/script/build-libpathrs.sh" "$LIBPATHRS_VERSION" "$dylibdir" "${arches[@]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For reproducible builds, add these to EXTRA_LDFLAGS:
|
# For reproducible builds, add these to EXTRA_LDFLAGS:
|
||||||
@@ -70,7 +73,7 @@ function build_project() {
|
|||||||
CFLAGS="$original_cflags"
|
CFLAGS="$original_cflags"
|
||||||
set_cross_vars "$arch"
|
set_cross_vars "$arch"
|
||||||
make -C "$root" \
|
make -C "$root" \
|
||||||
PKG_CONFIG_PATH="$seccompdir/$arch/lib/pkgconfig" \
|
PKG_CONFIG_PATH="$dylibdir/$arch/lib/pkgconfig" \
|
||||||
"${make_args[@]}"
|
"${make_args[@]}"
|
||||||
"$STRIP" "$root/$project"
|
"$STRIP" "$root/$project"
|
||||||
mv "$root/$project" "$builddir/$project.$arch"
|
mv "$root/$project" "$builddir/$project.$arch"
|
||||||
@@ -84,13 +87,8 @@ function build_project() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Copy libseccomp source tarball.
|
# Copy dylib source tarballs.
|
||||||
cp "$seccompdir"/src/* "$builddir"
|
cp "$dylibdir"/src/* "$builddir"
|
||||||
|
|
||||||
# Clean up.
|
|
||||||
if [ -n "$tempdir" ]; then
|
|
||||||
rm -rf "$tempdir"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# End of the easy-to-configure portion.
|
# End of the easy-to-configure portion.
|
||||||
|
|||||||
@@ -112,6 +112,9 @@ tmp_seccomp_gpgflags=("--homedir=$tmp_gpgdir" "--no-default-keyring" "--keyring=
|
|||||||
gpg "${tmp_seccomp_gpgflags[@]}" --recv-keys 0x47A68FCE37C7D7024FD65E11356CE62C2B524099
|
gpg "${tmp_seccomp_gpgflags[@]}" --recv-keys 0x47A68FCE37C7D7024FD65E11356CE62C2B524099
|
||||||
gpg "${tmp_seccomp_gpgflags[@]}" --recv-keys 0x7100AADFAE6E6E940D2E0AD655E45A5AE8CA7C8A
|
gpg "${tmp_seccomp_gpgflags[@]}" --recv-keys 0x7100AADFAE6E6E940D2E0AD655E45A5AE8CA7C8A
|
||||||
|
|
||||||
|
tmp_libpathrs_gpgflags=("--homedir=$tmp_gpgdir" "--no-default-keyring" "--keyring=libpathrs.keyring" "--keyserver=keys.openpgp.org")
|
||||||
|
gpg "${tmp_libpathrs_gpgflags[@]}" --recv-keys 0xC9C370B246B09F6DBCFC744C34401015D1D2D386
|
||||||
|
|
||||||
gpg "${gpgflags[@]}" --clear-sign <<<"[This is test text used for $project release scripts. $(date --rfc-email)]" |
|
gpg "${gpgflags[@]}" --clear-sign <<<"[This is test text used for $project release scripts. $(date --rfc-email)]" |
|
||||||
gpg "${tmp_runc_gpgflags[@]}" --verify || bail "Signing key ${keyid:-DEFAULT} is not in trusted $project.keyring list!"
|
gpg "${tmp_runc_gpgflags[@]}" --verify || bail "Signing key ${keyid:-DEFAULT} is not in trusted $project.keyring list!"
|
||||||
|
|
||||||
@@ -156,4 +159,7 @@ gpg "${tmp_runc_gpgflags[@]}" --verify "$project.$hashcmd"
|
|||||||
# Verify seccomp tarball.
|
# Verify seccomp tarball.
|
||||||
gpg "${tmp_seccomp_gpgflags[@]}" --verify libseccomp*.asc
|
gpg "${tmp_seccomp_gpgflags[@]}" --verify libseccomp*.asc
|
||||||
|
|
||||||
|
# Verify libpathrs tarball.
|
||||||
|
gpg "${tmp_libpathrs_gpgflags[@]}" --verify libpathrs*.asc
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -eux -o pipefail
|
set -eux -o pipefail
|
||||||
DNF=(dnf -y --setopt=install_weak_deps=False --setopt=tsflags=nodocs --exclude="kernel,kernel-core")
|
DNF=(dnf -y --setopt=install_weak_deps=False --setopt=tsflags=nodocs --exclude="kernel,kernel-core")
|
||||||
RPMS=(bats git-core glibc-static golang jq libseccomp-devel make)
|
RPMS=(bats git-core glibc-static golang jq libseccomp-devel cargo lld make wget)
|
||||||
# Work around dnf mirror failures by retrying a few times.
|
# Work around dnf mirror failures by retrying a few times.
|
||||||
for i in $(seq 0 2); do
|
for i in $(seq 0 2); do
|
||||||
sleep "$i"
|
sleep "$i"
|
||||||
@@ -16,11 +16,16 @@ fi
|
|||||||
|
|
||||||
dnf clean all
|
dnf clean all
|
||||||
|
|
||||||
|
SCRIPTDIR="$(dirname "${BASH_SOURCE[0]}")"
|
||||||
|
|
||||||
|
LIBPATHRS_VERSION="0.2.4"
|
||||||
|
"$SCRIPTDIR"/build-libpathrs.sh "$LIBPATHRS_VERSION" /usr
|
||||||
|
|
||||||
# To avoid "avc: denied { nosuid_transition }" from SELinux as we run tests on /tmp.
|
# To avoid "avc: denied { nosuid_transition }" from SELinux as we run tests on /tmp.
|
||||||
mount -o remount,suid /tmp
|
mount -o remount,suid /tmp
|
||||||
|
|
||||||
# Setup rootless user.
|
# Setup rootless user.
|
||||||
"$(dirname "${BASH_SOURCE[0]}")"/setup_rootless.sh
|
"$SCRIPTDIR"/setup_rootless.sh
|
||||||
|
|
||||||
# Delegate cgroup v2 controllers to rootless user via --systemd-cgroup
|
# Delegate cgroup v2 controllers to rootless user via --systemd-cgroup
|
||||||
mkdir -p /etc/systemd/system/user@.service.d
|
mkdir -p /etc/systemd/system/user@.service.d
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ is_allowed_fdtarget() {
|
|||||||
if ! is_allowed_fdtarget "$target"; then
|
if ! is_allowed_fdtarget "$target"; then
|
||||||
echo "Violation: FD $fd_name -> '$target'"
|
echo "Violation: FD $fd_name -> '$target'"
|
||||||
violation_found=1
|
violation_found=1
|
||||||
|
else
|
||||||
|
echo "Permitted: FD $fd_name -> '$target'"
|
||||||
fi
|
fi
|
||||||
done < <(find "/proc/$pid/fd" -type l -print0)
|
done < <(find "/proc/$pid/fd" -type l -print0)
|
||||||
[ "$violation_found" -eq 0 ]
|
[ "$violation_found" -eq 0 ]
|
||||||
|
|||||||
+1
-1
@@ -1,8 +1,8 @@
|
|||||||
# SPDX-License-Identifier: MPL-2.0
|
# SPDX-License-Identifier: MPL-2.0
|
||||||
#
|
#
|
||||||
# libpathrs: safe path resolution on Linux
|
# libpathrs: safe path resolution on Linux
|
||||||
# Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
# Copyright (C) 2019-2025 SUSE LLC
|
# 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
|
# 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
|
# 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
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
/*
|
/*
|
||||||
* libpathrs: safe path resolution on Linux
|
* libpathrs: safe path resolution on Linux
|
||||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
* Copyright (C) 2019-2025 SUSE LLC
|
* 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
|
* 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
|
* 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
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
/*
|
/*
|
||||||
* libpathrs: safe path resolution on Linux
|
* libpathrs: safe path resolution on Linux
|
||||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
* Copyright (C) 2019-2025 SUSE LLC
|
* 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
|
* 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
|
* 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].
|
// you can try to use [Root.Open] or [Root.OpenFile].
|
||||||
//
|
//
|
||||||
// It is critical that perform all relevant operations through this [Handle]
|
// 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
|
// because the security properties of libpathrs depend on users doing all
|
||||||
// relevant filesystem operations through libpathrs.
|
// relevant filesystem operations through libpathrs.
|
||||||
//
|
|
||||||
// [os.File]: https://pkg.go.dev/os#File
|
|
||||||
type Handle struct {
|
type Handle struct {
|
||||||
inner *os.File
|
inner *os.File
|
||||||
}
|
}
|
||||||
@@ -43,7 +41,7 @@ type Handle struct {
|
|||||||
// handle will be copied by this method, so the original handle should still be
|
// handle will be copied by this method, so the original handle should still be
|
||||||
// freed by the caller.
|
// 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.
|
// for "deserialising" pathrs root handles.
|
||||||
func HandleFromFile(file *os.File) (*Handle, error) {
|
func HandleFromFile(file *os.File) (*Handle, error) {
|
||||||
newFile, err := fdutils.DupFile(file)
|
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].
|
// 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
|
// If you want to get an independent copy, use [Handle.Clone] followed by
|
||||||
// [Handle.IntoFile] on the cloned [Handle].
|
// [Handle.IntoFile] on the cloned [Handle].
|
||||||
//
|
|
||||||
// [os.File]: https://pkg.go.dev/os#File
|
|
||||||
func (h *Handle) IntoFile() *os.File {
|
func (h *Handle) IntoFile() *os.File {
|
||||||
// TODO: Figure out if we really don't want to make a copy.
|
// 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
|
// 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
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
/*
|
/*
|
||||||
* libpathrs: safe path resolution on Linux
|
* libpathrs: safe path resolution on Linux
|
||||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
* Copyright (C) 2019-2025 SUSE LLC
|
* 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
|
* 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
|
* 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
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
/*
|
/*
|
||||||
* libpathrs: safe path resolution on Linux
|
* libpathrs: safe path resolution on Linux
|
||||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
* Copyright (C) 2019-2025 SUSE LLC
|
* 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
|
* 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
|
* 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
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
/*
|
/*
|
||||||
* libpathrs: safe path resolution on Linux
|
* libpathrs: safe path resolution on Linux
|
||||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
* Copyright (C) 2019-2025 SUSE LLC
|
* 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
|
* 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
|
* 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
|
size := 128
|
||||||
for {
|
for {
|
||||||
linkBuf := make([]byte, size)
|
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 {
|
switch {
|
||||||
case int(n) < C.__PATHRS_MAX_ERR_VALUE:
|
case int(n) < C.__PATHRS_MAX_ERR_VALUE:
|
||||||
return "", fetchError(n)
|
return "", fetchError(n)
|
||||||
@@ -301,7 +301,7 @@ func ProcReadlinkat(procRootFd int, base ProcBase, path string) (string, error)
|
|||||||
linkBuf := make([]byte, size)
|
linkBuf := make([]byte, size)
|
||||||
n := C.pathrs_proc_readlinkat(
|
n := C.pathrs_proc_readlinkat(
|
||||||
C.int(procRootFd), cBase, cPath,
|
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 {
|
switch {
|
||||||
case int(n) < C.__PATHRS_MAX_ERR_VALUE:
|
case int(n) < C.__PATHRS_MAX_ERR_VALUE:
|
||||||
return "", fetchError(n)
|
return "", fetchError(n)
|
||||||
|
|||||||
+4
-11
@@ -3,8 +3,8 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
/*
|
/*
|
||||||
* libpathrs: safe path resolution on Linux
|
* libpathrs: safe path resolution on Linux
|
||||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
* Copyright (C) 2019-2025 SUSE LLC
|
* 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
|
* 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
|
* 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
|
// *before* you call wait(2)or any equivalent method that could reap
|
||||||
// zombies).
|
// zombies).
|
||||||
func ProcPid(pid int) ProcBase {
|
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?
|
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
|
// ThreadCloser is a callback that needs to be called when you are done
|
||||||
// operating on an [os.File] fetched using [Handle.OpenThreadSelf].
|
// operating on an [os.File] fetched using [Handle.OpenThreadSelf].
|
||||||
//
|
|
||||||
// [os.File]: https://pkg.go.dev/os#File
|
|
||||||
type ThreadCloser func()
|
type ThreadCloser func()
|
||||||
|
|
||||||
// Handle is a wrapper around an *os.File handle to "/proc", which can be
|
// 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
|
// Unlike [Handle.OpenThreadSelf], this method does not involve locking
|
||||||
// the goroutine to the current OS thread and so is simpler to use and
|
// the goroutine to the current OS thread and so is simpler to use and
|
||||||
// theoretically has slightly less overhead.
|
// theoretically has slightly less overhead.
|
||||||
//
|
|
||||||
// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread
|
|
||||||
func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) {
|
func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) {
|
||||||
file, closer, err := proc.open(ProcSelf, path, flags)
|
file, closer, err := proc.open(ProcSelf, path, flags)
|
||||||
if closer != nil {
|
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
|
// callback MUST be called AFTER you have finished using the returned
|
||||||
// [os.File]. This callback is completely separate to [os.File.Close], so it
|
// [os.File]. This callback is completely separate to [os.File.Close], so it
|
||||||
// must be called regardless of how you close the handle.
|
// 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) {
|
func (proc *Handle) OpenThreadSelf(path string, flags int) (*os.File, ThreadCloser, error) {
|
||||||
return proc.open(ProcThreadSelf, path, flags)
|
return proc.open(ProcThreadSelf, path, flags)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-28
@@ -3,8 +3,8 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
/*
|
/*
|
||||||
* libpathrs: safe path resolution on Linux
|
* libpathrs: safe path resolution on Linux
|
||||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
* Copyright (C) 2019-2025 SUSE LLC
|
* 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
|
* 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
|
* 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.
|
// still be closed by the caller.
|
||||||
//
|
//
|
||||||
// This is effectively the inverse operation of [Root.IntoFile].
|
// This is effectively the inverse operation of [Root.IntoFile].
|
||||||
//
|
|
||||||
// [os.File]: https://pkg.go.dev/os#File
|
|
||||||
func RootFromFile(file *os.File) (*Root, error) {
|
func RootFromFile(file *os.File) (*Root, error) {
|
||||||
newFile, err := fdutils.DupFile(file)
|
newFile, err := fdutils.DupFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -109,8 +107,6 @@ func (r *Root) ResolveNoFollow(path string) (*Handle, error) {
|
|||||||
// ergonomic to use.
|
// ergonomic to use.
|
||||||
//
|
//
|
||||||
// This is effectively equivalent to [os.Open].
|
// This is effectively equivalent to [os.Open].
|
||||||
//
|
|
||||||
// [os.Open]: https://pkg.go.dev/os#Open
|
|
||||||
func (r *Root) Open(path string) (*os.File, error) {
|
func (r *Root) Open(path string) (*os.File, error) {
|
||||||
return r.OpenFile(path, os.O_RDONLY)
|
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
|
// This is effectively equivalent to [os.OpenFile], except that os.O_CREAT is
|
||||||
// not supported.
|
// not supported.
|
||||||
//
|
|
||||||
// [os.OpenFile]: https://pkg.go.dev/os#OpenFile
|
|
||||||
func (r *Root) OpenFile(path string, flags int) (*os.File, error) {
|
func (r *Root) OpenFile(path string, flags int) (*os.File, error) {
|
||||||
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) {
|
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) {
|
||||||
fd, err := libpathrs.InRootOpen(rootFd, path, flags)
|
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
|
// Unlike [os.Create], if the file already exists an error is created rather
|
||||||
// than the file being opened and truncated.
|
// 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) {
|
func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error) {
|
||||||
unixMode, err := toUnixMode(mode, false)
|
unixMode, err := toUnixMode(mode, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -194,8 +186,6 @@ func (r *Root) RemoveFile(path string) error {
|
|||||||
// directory tree.
|
// directory tree.
|
||||||
//
|
//
|
||||||
// This is effectively equivalent to [os.Remove].
|
// This is effectively equivalent to [os.Remove].
|
||||||
//
|
|
||||||
// [os.Remove]: https://pkg.go.dev/os#Remove
|
|
||||||
func (r *Root) Remove(path string) error {
|
func (r *Root) Remove(path string) error {
|
||||||
// In order to match os.Remove's implementation we need to also do both
|
// In order to match os.Remove's implementation we need to also do both
|
||||||
// syscalls unconditionally and adjust the error based on whether
|
// 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.
|
// RemoveAll recursively deletes a path and all of its children.
|
||||||
//
|
//
|
||||||
// This is effectively equivalent to [os.RemoveAll].
|
// This is effectively equivalent to [os.RemoveAll].
|
||||||
//
|
|
||||||
// [os.RemoveAll]: https://pkg.go.dev/os#RemoveAll
|
|
||||||
func (r *Root) RemoveAll(path string) error {
|
func (r *Root) RemoveAll(path string) error {
|
||||||
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
|
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
|
||||||
err := libpathrs.InRootRemoveAll(rootFd, path)
|
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).
|
// mode is used for the new directory (the process's umask applies).
|
||||||
//
|
//
|
||||||
// This is effectively equivalent to [os.Mkdir].
|
// 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 {
|
func (r *Root) Mkdir(path string, mode os.FileMode) error {
|
||||||
unixMode, err := toUnixMode(mode, false)
|
unixMode, err := toUnixMode(mode, false)
|
||||||
if err != nil {
|
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).
|
// directories created by this function (the process's umask applies).
|
||||||
//
|
//
|
||||||
// This is effectively equivalent to [os.MkdirAll].
|
// 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) {
|
func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) {
|
||||||
unixMode, err := toUnixMode(mode, false)
|
unixMode, err := toUnixMode(mode, false)
|
||||||
if err != nil {
|
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
|
// directory tree. The provided mode is used for the new directory (the
|
||||||
// process's umask applies).
|
// process's umask applies).
|
||||||
//
|
//
|
||||||
// This is effectively equivalent to [unix.Mknod].
|
// This is effectively equivalent to [golang.org/x/sys/unix.Mknod].
|
||||||
//
|
|
||||||
// [unix.Mknod]: https://pkg.go.dev/golang.org/x/sys/unix#Mknod
|
|
||||||
func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error {
|
func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error {
|
||||||
unixMode, err := toUnixMode(mode, true)
|
unixMode, err := toUnixMode(mode, true)
|
||||||
if err != nil {
|
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.
|
// created at path and is a link to target.
|
||||||
//
|
//
|
||||||
// This is effectively equivalent to [os.Symlink].
|
// This is effectively equivalent to [os.Symlink].
|
||||||
//
|
|
||||||
// [os.Symlink]: https://pkg.go.dev/os#Symlink
|
|
||||||
func (r *Root) Symlink(path, target string) error {
|
func (r *Root) Symlink(path, target string) error {
|
||||||
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
|
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
|
||||||
err := libpathrs.InRootSymlink(rootFd, path, target)
|
err := libpathrs.InRootSymlink(rootFd, path, target)
|
||||||
@@ -314,8 +294,6 @@ func (r *Root) Symlink(path, target string) error {
|
|||||||
// host).
|
// host).
|
||||||
//
|
//
|
||||||
// This is effectively equivalent to [os.Link].
|
// This is effectively equivalent to [os.Link].
|
||||||
//
|
|
||||||
// [os.Link]: https://pkg.go.dev/os#Link
|
|
||||||
func (r *Root) Hardlink(path, target string) error {
|
func (r *Root) Hardlink(path, target string) error {
|
||||||
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
|
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
|
||||||
err := libpathrs.InRootHardlink(rootFd, path, target)
|
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.
|
// Readlink returns the target of a symlink with a [Root]'s directory tree.
|
||||||
//
|
//
|
||||||
// This is effectively equivalent to [os.Readlink].
|
// This is effectively equivalent to [os.Readlink].
|
||||||
//
|
|
||||||
// [os.Readlink]: https://pkg.go.dev/os#Readlink
|
|
||||||
func (r *Root) Readlink(path string) (string, error) {
|
func (r *Root) Readlink(path string) (string, error) {
|
||||||
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (string, error) {
|
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (string, error) {
|
||||||
return libpathrs.InRootReadlink(rootFd, path)
|
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].
|
// 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
|
// If you want to get an independent copy, use [Root.Clone] followed by
|
||||||
// [Root.IntoFile] on the cloned [Root].
|
// [Root.IntoFile] on the cloned [Root].
|
||||||
//
|
|
||||||
// [os.File]: https://pkg.go.dev/os#File
|
|
||||||
func (r *Root) IntoFile() *os.File {
|
func (r *Root) IntoFile() *os.File {
|
||||||
// TODO: Figure out if we really don't want to make a copy.
|
// 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
|
// 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
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
/*
|
/*
|
||||||
* libpathrs: safe path resolution on Linux
|
* libpathrs: safe path resolution on Linux
|
||||||
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
|
|
||||||
* Copyright (C) 2019-2025 SUSE LLC
|
* 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
|
* 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
|
* 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
|
## explicit; go 1.18
|
||||||
cyphar.com/go-pathrs
|
cyphar.com/go-pathrs
|
||||||
cyphar.com/go-pathrs/internal/fdutils
|
cyphar.com/go-pathrs/internal/fdutils
|
||||||
|
|||||||
Reference in New Issue
Block a user