nsinit.Init() restores parent death signal before exec

Docker-DCO-1.1-Signed-off-by: Bernerd Schaefer <bj.schaefer@gmail.com> (github: bernerdschaefer)
This commit is contained in:
Bernerd Schaefer 2014-05-14 11:49:06 +02:00
parent 15e734a277
commit 1c33652c66
1 changed files with 41 additions and 0 deletions

View File

@ -85,12 +85,53 @@ func Init(container *libcontainer.Container, uncleanRootfs, consolePath string,
return err return err
} }
} }
pdeathSignal, err := system.GetParentDeathSignal()
if err != nil {
return fmt.Errorf("get parent death signal %s", err)
}
if err := FinalizeNamespace(container); err != nil { if err := FinalizeNamespace(container); err != nil {
return fmt.Errorf("finalize namespace %s", err) return fmt.Errorf("finalize namespace %s", err)
} }
// FinalizeNamespace can change user/group which clears the parent death
// signal, so we restore it here.
if err := RestoreParentDeathSignal(pdeathSignal); err != nil {
return fmt.Errorf("restore parent death signal %s", err)
}
return system.Execv(args[0], args[0:], container.Env) return system.Execv(args[0], args[0:], container.Env)
} }
// RestoreParentDeathSignal sets the parent death signal to old.
func RestoreParentDeathSignal(old int) error {
if old == 0 {
return nil
}
current, err := system.GetParentDeathSignal()
if err != nil {
return fmt.Errorf("get parent death signal %s", err)
}
if old == current {
return nil
}
if err := system.ParentDeathSignal(uintptr(old)); err != nil {
return fmt.Errorf("set parent death signal %s", err)
}
// Signal self if parent is already dead. Does nothing if running in a new
// PID namespace, as Getppid will always return 0.
if syscall.Getppid() == 1 {
return syscall.Kill(syscall.Getpid(), syscall.Signal(old))
}
return nil
}
// SetupUser changes the groups, gid, and uid for the user inside the container // SetupUser changes the groups, gid, and uid for the user inside the container
func SetupUser(u string) error { func SetupUser(u string) error {
uid, gid, suppGids, err := user.GetUserGroupSupplementary(u, syscall.Getuid(), syscall.Getgid()) uid, gid, suppGids, err := user.GetUserGroupSupplementary(u, syscall.Getuid(), syscall.Getgid())