|
@@ -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())
|