VYPR
Medium severity6.4NVD Advisory· Published Jan 31, 2017· Updated May 13, 2026

CVE-2016-9962

CVE-2016-9962

Description

RunC allowed additional container processes via 'runc exec' to be ptraced by the pid 1 of the container. This allows the main processes of the container, if running as root, to gain access to file-descriptors of these new processes during the initialization and can lead to container escapes or modification of runC state before the process is fully placed inside the container.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/opencontainers/runcGo
< 1.0.0-rc31.0.0-rc3

Patches

2
50a19c6ff828

Set init processes as non-dumpable

https://github.com/opencontainers/runcMichael CrosbyDec 7, 2016via ghsa
4 files changed · +16 2
  • libcontainer/init_linux.go+2 1 modified
    @@ -77,7 +77,8 @@ func newContainerInit(t initType, pipe *os.File, stateDirFD int) (initer, error)
     	switch t {
     	case initSetns:
     		return &linuxSetnsInit{
    -			config: config,
    +			config:     config,
    +			stateDirFD: stateDirFD,
     		}, nil
     	case initStandard:
     		return &linuxStandardInit{
    
  • libcontainer/nsenter/nsexec.c+5 0 modified
    @@ -408,6 +408,11 @@ void nsexec(void)
     	if (pipenum == -1)
     		return;
     
    +	/* make the process non-dumpable */
    +	if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) {
    +		bail("failed to set process as non-dumpable");
    +	}
    +
     	/* Parse all of the netlink configuration. */
     	nl_parse(pipenum, &config);
     
    
  • libcontainer/setns_init_linux.go+6 1 modified
    @@ -5,6 +5,7 @@ package libcontainer
     import (
     	"fmt"
     	"os"
    +	"syscall"
     
     	"github.com/opencontainers/runc/libcontainer/apparmor"
     	"github.com/opencontainers/runc/libcontainer/keys"
    @@ -16,7 +17,8 @@ import (
     // linuxSetnsInit performs the container's initialization for running a new process
     // inside an existing container.
     type linuxSetnsInit struct {
    -	config *initConfig
    +	config     *initConfig
    +	stateDirFD int
     }
     
     func (l *linuxSetnsInit) getSessionRingName() string {
    @@ -49,5 +51,8 @@ func (l *linuxSetnsInit) Init() error {
     	if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
     		return err
     	}
    +	// close the statedir fd before exec because the kernel resets dumpable in the wrong order
    +	// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
    +	syscall.Close(l.stateDirFD)
     	return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
     }
    
  • libcontainer/standard_init_linux.go+3 0 modified
    @@ -171,6 +171,9 @@ func (l *linuxStandardInit) Init() error {
     			return newSystemErrorWithCause(err, "init seccomp")
     		}
     	}
    +	// close the statedir fd before exec because the kernel resets dumpable in the wrong order
    +	// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
    +	syscall.Close(l.stateDirFD)
     	if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil {
     		return newSystemErrorWithCause(err, "exec user process")
     	}
    
5d93fed3d27f

Set init processes as non-dumpable

https://github.com/opencontainers/runcMichael CrosbyDec 7, 2016via ghsa
4 files changed · +18 4
  • libcontainer/init_linux.go+3 2 modified
    @@ -77,8 +77,9 @@ func newContainerInit(t initType, pipe *os.File, stateDirFD int) (initer, error)
     	switch t {
     	case initSetns:
     		return &linuxSetnsInit{
    -			pipe:   pipe,
    -			config: config,
    +			pipe:       pipe,
    +			config:     config,
    +			stateDirFD: stateDirFD,
     		}, nil
     	case initStandard:
     		return &linuxStandardInit{
    
  • libcontainer/nsenter/nsexec.c+5 0 modified
    @@ -424,6 +424,11 @@ void nsexec(void)
     	if (pipenum == -1)
     		return;
     
    +	/* make the process non-dumpable */
    +	if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) {
    +		bail("failed to set process as non-dumpable");
    +	}
    +
     	/* Parse all of the netlink configuration. */
     	nl_parse(pipenum, &config);
     
    
  • libcontainer/setns_init_linux.go+7 2 modified
    @@ -5,6 +5,7 @@ package libcontainer
     import (
     	"fmt"
     	"os"
    +	"syscall"
     
     	"github.com/opencontainers/runc/libcontainer/apparmor"
     	"github.com/opencontainers/runc/libcontainer/keys"
    @@ -16,8 +17,9 @@ import (
     // linuxSetnsInit performs the container's initialization for running a new process
     // inside an existing container.
     type linuxSetnsInit struct {
    -	pipe   *os.File
    -	config *initConfig
    +	pipe       *os.File
    +	config     *initConfig
    +	stateDirFD int
     }
     
     func (l *linuxSetnsInit) getSessionRingName() string {
    @@ -58,5 +60,8 @@ func (l *linuxSetnsInit) Init() error {
     	if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
     		return err
     	}
    +	// close the statedir fd before exec because the kernel resets dumpable in the wrong order
    +	// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
    +	syscall.Close(l.stateDirFD)
     	return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
     }
    
  • libcontainer/standard_init_linux.go+3 0 modified
    @@ -179,6 +179,9 @@ func (l *linuxStandardInit) Init() error {
     			return newSystemErrorWithCause(err, "init seccomp")
     		}
     	}
    +	// close the statedir fd before exec because the kernel resets dumpable in the wrong order
    +	// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
    +	syscall.Close(l.stateDirFD)
     	if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil {
     		return newSystemErrorWithCause(err, "exec user process")
     	}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

24

News mentions

0

No linked articles in our index yet.