File tree Expand file tree Collapse file tree 4 files changed +37
-0
lines changed Expand file tree Collapse file tree 4 files changed +37
-0
lines changed Original file line number Diff line number Diff line change @@ -388,11 +388,21 @@ func (c *Container) Signal(s os.Signal) error {
388388 // leftover processes. Handle this special case here.
389389 if s == unix .SIGKILL && ! c .config .Namespaces .IsPrivate (configs .NEWPID ) {
390390 if err := signalAllProcesses (c .cgroupManager , unix .SIGKILL ); err != nil {
391+ if c .config .RootlessCgroups { // may not have an access to cgroup
392+ logrus .WithError (err ).Warn ("failed to kill all processes, possibly due to lack of cgroup (Hint: enable cgroup v2 delegation)" )
393+ // Some processes may leak when cgroup is not delegated
394+ // https://github.com/opencontainers/runc/pull/4395#pullrequestreview-2291179652
395+ return c .signal (s )
396+ }
391397 return fmt .Errorf ("unable to kill all processes: %w" , err )
392398 }
393399 return nil
394400 }
395401
402+ return c .signal (s )
403+ }
404+
405+ func (c * Container ) signal (s os.Signal ) error {
396406 // To avoid a PID reuse attack, don't kill non-running container.
397407 if ! c .hasInit () {
398408 return ErrNotRunning
Original file line number Diff line number Diff line change @@ -695,6 +695,8 @@ func setupPersonality(config *configs.Config) error {
695695
696696// signalAllProcesses freezes then iterates over all the processes inside the
697697// manager's cgroups sending the signal s to them.
698+ //
699+ // signalAllProcesses returns ErrNotRunning when the cgroup does not exist.
698700func signalAllProcesses (m cgroups.Manager , s unix.Signal ) error {
699701 if ! m .Exists () {
700702 return ErrNotRunning
Original file line number Diff line number Diff line change @@ -44,6 +44,7 @@ func destroy(c *Container) error {
4444 // and destroy is supposed to remove all the container resources, we need
4545 // to kill those processes here.
4646 if ! c .config .Namespaces .IsPrivate (configs .NEWPID ) {
47+ // Likely to fail when c.config.RootlessCgroups is true
4748 _ = signalAllProcesses (c .cgroupManager , unix .SIGKILL )
4849 }
4950 if err := c .cgroupManager .Destroy (); err != nil {
Original file line number Diff line number Diff line change @@ -133,3 +133,27 @@ test_host_pidns_kill() {
133133 test_host_pidns_kill
134134 unset KILL_INIT
135135}
136+
137+ # https://github.com/opencontainers/runc/issues/4394 (cgroup v1, rootless)
138+ @test " kill KILL [shared pidns]" {
139+ update_config ' .process.args = ["sleep", "infinity"]'
140+
141+ runc run -d --console-socket " $CONSOLE_SOCKET " target_ctr
142+ [ " $status " -eq 0 ]
143+ testcontainer target_ctr running
144+ target_pid=" $( __runc state target_ctr | jq .pid) "
145+ update_config ' .linux.namespaces |= map(if .type == "user" or .type == "pid" then (.path = "/proc/' " $target_pid " ' /ns/" + .type) else . end) | del(.linux.uidMappings) | del(.linux.gidMappings)'
146+
147+ runc run -d --console-socket " $CONSOLE_SOCKET " attached_ctr
148+ [ " $status " -eq 0 ]
149+ testcontainer attached_ctr running
150+
151+ runc kill attached_ctr 9
152+ [ " $status " -eq 0 ]
153+
154+ runc delete --force attached_ctr
155+ [ " $status " -eq 0 ]
156+
157+ runc delete --force target_ctr
158+ [ " $status " -eq 0 ]
159+ }
You can’t perform that action at this time.
0 commit comments