From f7dda6e6dc4ccfb69c5e2a1cbae9b25cf60d7ac6 Mon Sep 17 00:00:00 2001 From: lifubang Date: Thu, 25 Sep 2025 09:39:29 +0000 Subject: [PATCH 1/2] libct: setup personality before initializing seccomp Set the process personality early to ensure it takes effect before seccomp is initialized. If seccomp filters are applied first and they block personality-related system calls (e.g., `personality(2)`), subsequent attempts to set the personality will fail. Signed-off-by: lifubang --- libcontainer/setns_init_linux.go | 13 ++++++++----- libcontainer/standard_init_linux.go | 14 +++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go index a3d9a8d92af..2bdaa4de8d5 100644 --- a/libcontainer/setns_init_linux.go +++ b/libcontainer/setns_init_linux.go @@ -80,6 +80,14 @@ func (l *linuxSetnsInit) Init() error { if err := setupIOPriority(l.config); err != nil { return err } + + // Set personality if specified. + if l.config.Config.Personality != nil { + if err := setupPersonality(l.config.Config); err != nil { + return err + } + } + // Tell our parent that we're ready to exec. This must be done before the // Seccomp rules have been applied, because we need to be able to read and // write to a socket. @@ -110,11 +118,6 @@ func (l *linuxSetnsInit) Init() error { if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil { return err } - if l.config.Config.Personality != nil { - if err := setupPersonality(l.config.Config); err != nil { - return err - } - } // Check for the arg early to make sure it exists. name, err := exec.LookPath(l.config.Args[0]) if err != nil { diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index 6bf5ba39cc8..901bd394e6a 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -164,6 +164,13 @@ func (l *linuxStandardInit) Init() error { return err } + // Set personality if specified. + if l.config.Config.Personality != nil { + if err := setupPersonality(l.config.Config); err != nil { + return err + } + } + // Tell our parent that we're ready to exec. This must be done before the // Seccomp rules have been applied, because we need to be able to read and // write to a socket. @@ -238,13 +245,6 @@ func (l *linuxStandardInit) Init() error { } } - // Set personality if specified. - if l.config.Config.Personality != nil { - if err := setupPersonality(l.config.Config); err != nil { - return err - } - } - // Close the pipe to signal that we have completed our init. logrus.Debugf("init: closing the pipe to signal completion") _ = l.pipe.Close() From 57f1bef4226e0bc94189610d4cccb1d5aafca19e Mon Sep 17 00:00:00 2001 From: lifubang Date: Thu, 25 Sep 2025 09:41:27 +0000 Subject: [PATCH 2/2] test: runc run with personality syscall blocked by seccomp Signed-off-by: lifubang --- tests/integration/personality.bats | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/integration/personality.bats b/tests/integration/personality.bats index 37aa8e86fda..94e2ac1b25e 100644 --- a/tests/integration/personality.bats +++ b/tests/integration/personality.bats @@ -62,3 +62,21 @@ function teardown() { [ "$status" -eq 0 ] [[ "$output" == *"x86_64"* ]] } + +# check that personality can be set when the personality syscall is blocked by seccomp +@test "runc run with personality syscall blocked by seccomp" { + update_config ' + .linux.personality = { + "domain": "LINUX", + } + | .linux.seccomp = { + "defaultAction":"SCMP_ACT_ALLOW", + "syscalls":[{"names":["personality"], "action":"SCMP_ACT_ERRNO"}] + }' + + runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox + [ "$status" -eq 0 ] + runc exec test_busybox /bin/sh -c "uname -a" + [ "$status" -eq 0 ] + [[ "$output" == *"x86_64"* ]] +}