From 83ecd11c29ac8e6791c2f3d55aba64766f8e3524 Mon Sep 17 00:00:00 2001 From: lifubang Date: Tue, 30 Apr 2024 23:41:36 +0800 Subject: [PATCH] runc exec: setupRlimits after syscall.rlimit.init() completed Issue: https://github.com/opencontainers/runc/issues/4195 Since https://go-review.googlesource.com/c/go/+/476097, there is a get/set race between runc exec and syscall.rlimit.init, so we need to call setupRlimits after syscall.rlimit.init() completed. Signed-off-by: lifubang (cherry picked from commit a853a82677daf631d472b5c842d4182135cd1813) Signed-off-by: lifubang --- libcontainer/process_linux.go | 18 ++++++++++-------- libcontainer/setns_init_linux.go | 8 ++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go index 0d9ceb9c9..ac3b104ea 100644 --- a/libcontainer/process_linux.go +++ b/libcontainer/process_linux.go @@ -152,11 +152,7 @@ func (p *setnsProcess) start() (retErr error) { } } } - // set rlimits, this has to be done here because we lose permissions - // to raise the limits once we enter a user-namespace - if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil { - return fmt.Errorf("error setting rlimits for process: %w", err) - } + if err := utils.WriteJSON(p.messageSockPair.parent, p.config); err != nil { return fmt.Errorf("error writing config to pipe: %w", err) } @@ -164,8 +160,14 @@ func (p *setnsProcess) start() (retErr error) { ierr := parseSync(p.messageSockPair.parent, func(sync *syncT) error { switch sync.Type { case procReady: - // This shouldn't happen. - panic("unexpected procReady in setns") + // Set rlimits, this has to be done here because we lose permissions + // to raise the limits once we enter a user-namespace + if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil { + return fmt.Errorf("error setting rlimits for ready process: %w", err) + } + + // Sync with child. + return writeSync(p.messageSockPair.parent, procRun) case procHooks: // This shouldn't happen. panic("unexpected procHooks in setns") @@ -495,7 +497,7 @@ func (p *initProcess) start() (retErr error) { return err } case procReady: - // set rlimits, this has to be done here because we lose permissions + // Set rlimits, this has to be done here because we lose permissions // to raise the limits once we enter a user-namespace if err := setupRlimits(p.config.Rlimits, p.pid()); err != nil { return fmt.Errorf("error setting rlimits for ready process: %w", err) diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go index d1bb12273..5c8d1382f 100644 --- a/libcontainer/setns_init_linux.go +++ b/libcontainer/setns_init_linux.go @@ -61,6 +61,14 @@ func (l *linuxSetnsInit) Init() error { 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. + if err := syncParentReady(l.pipe); err != nil { + return fmt.Errorf("sync ready: %w", err) + } + if err := selinux.SetExecLabel(l.config.ProcessLabel); err != nil { return err }