Skip to content

Commit

Permalink
enable preserve-argv0 by default on mainline
Browse files Browse the repository at this point in the history
P flag is needed in order for qemu to not lose
argv0 value. Problem is that qemu can only detect that
flag was set on 5.12+ kernels and if it doesn’t detect
it then all argument values are wrong.

This introduces a patch that is enabled on mainline
target that assumes P flag was set if the kernel does
not provide any flags.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
  • Loading branch information
tonistiigi committed Jan 21, 2022
1 parent eed5db1 commit c5e2139
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 2 deletions.
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ RUN git clone $QEMU_REPO && cd qemu && git checkout $QEMU_VERSION
COPY patches patches
ARG QEMU_PATCHES=cpu-max
ARG QEMU_PATCHES_ALL=${QEMU_PATCHES},alpine-patches,zero-init-msghdr,sched
ARG QEMU_PRESERVE_ARGV0
RUN <<eof
set -ex
if [ "${QEMU_PATCHES_ALL#*alpine-patches}" != "${QEMU_PATCHES_ALL}" ]; then
Expand All @@ -35,6 +36,9 @@ RUN <<eof
cp -a community/qemu/*.patch ../patches/alpine-patches/
cd - && rm -rf aports
fi
if [ -n "${QEMU_PRESERVE_ARGV0}" ]; then
QEMU_PATCHES_ALL="${QEMU_PATCHES_ALL},preserve-argv0"
fi
cd qemu
for p in $(echo $QEMU_PATCHES_ALL | tr ',' '\n'); do
for f in ../patches/$p/*.patch; do echo "apply $f"; patch -p1 < $f; done
Expand Down Expand Up @@ -107,5 +111,7 @@ RUN ./run.sh
FROM scratch
COPY --from=binaries / /usr/bin/
COPY --from=binfmt /go/bin/binfmt /usr/bin/binfmt
ARG QEMU_PRESERVE_ARGV0
ENV QEMU_PRESERVE_ARGV0=${QEMU_PRESERVE_ARGV0}
ENTRYPOINT [ "/usr/bin/binfmt" ]
VOLUME /tmp
2 changes: 1 addition & 1 deletion cmd/binfmt/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func install(arch string) error {
binaryPath = v
}
flags := "CF"
if v := os.Getenv("QEMU_PRESERVE_PARENT"); v != "" {
if v := os.Getenv("QEMU_PRESERVE_ARGV0"); v != "" {
flags += "P"
}
binaryBasename := cfg.binary
Expand Down
2 changes: 2 additions & 0 deletions docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ target "mainline" {
args = {
QEMU_REPO = QEMU_REPO
QEMU_VERSION = QEMU_VERSION
QEMU_PRESERVE_ARGV0 = "1"
}
cache-to = ["type=inline"]
cache-from = ["${REPO}:master"]
Expand All @@ -54,6 +55,7 @@ target "buildkit" {
args = {
BINARY_PREFIX = "buildkit-"
QEMU_PATCHES = "cpu-max,buildkit-direct-execve-v6.1"
QEMU_PRESERVE_ARGV0 = ""
}
cache-from = ["${REPO}:buildkit-master"]
target = "binaries"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
From eb4410de7f5297c643081e79a89f226210e3f4dd Mon Sep 17 00:00:00 2001
From: Tonis Tiigi <tonistiigi@gmail.com>
Date: Thu, 20 Jan 2022 20:21:07 -0800
Subject: [PATCH] linux-user: default to preserve-argv0

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
---
linux-user/main.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 37ed50d98e..87e76845dc 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -706,6 +706,11 @@ int main(int argc, char **argv, char **envp)
* get binfmt_misc flags
*/
preserve_argv0 = !!(qemu_getauxval(AT_FLAGS) & AT_FLAGS_PRESERVE_ARGV0);
+
+ // default to preserve_argv0 on older kernels
+ if (qemu_getauxval(AT_FLAGS) == 0) {
+ preserve_argv0 = 1;
+ }

/*
* Manage binfmt-misc preserve-arg[0] flag
--
2.32.0 (Apple Git-132)

2 changes: 1 addition & 1 deletion test/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ FROM alpine AS run
RUN apk add libcap
COPY --from=binary / /usr/bin
ARG CONFIG_RT_GROUP_SCHED
RUN --security=insecure /usr/bin/test -test.v
RUN --security=insecure REEXEC_NAME=/usr/bin/test /usr/bin/test -test.v

FROM binary
33 changes: 33 additions & 0 deletions test/argv0_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package tests

import (
"fmt"
"os"
"os/exec"
"strings"
"testing"

"github.com/stretchr/testify/require"
)

func init() {
if v := os.Getenv("BINFMT_ARGV0_TEST"); v != "" {
fmt.Println(strings.Join(os.Args, ","))
os.Exit(0)
}
}

func TestArgv0(t *testing.T) {
self := "/proc/self/exe"
if v, ok := os.LookupEnv("REEXEC_NAME"); ok {
self = v
}
cmd := &exec.Cmd{
Path: self,
Env: []string{"BINFMT_ARGV0_TEST=1"},
Args: []string{"first", "second", "third"},
}
out, err := cmd.CombinedOutput()
require.Equal(t, "first,second,third\n", string(out))
require.NoError(t, err)
}

0 comments on commit c5e2139

Please sign in to comment.