(p *Process)
| 494 | } |
| 495 | |
| 496 | func (c *Container) newParentProcess(p *Process) (parentProcess, error) { |
| 497 | comm, err := newProcessComm() |
| 498 | if err != nil { |
| 499 | return nil, err |
| 500 | } |
| 501 | |
| 502 | // Make sure we use a new safe copy of /proc/self/exe binary each time, this |
| 503 | // is called to make sure that if a container manages to overwrite the file, |
| 504 | // it cannot affect other containers on the system. For runc, this code will |
| 505 | // only ever be called once, but libcontainer users might call this more than |
| 506 | // once. |
| 507 | p.closeClonedExes() |
| 508 | var ( |
| 509 | exePath string |
| 510 | safeExe *os.File |
| 511 | ) |
| 512 | if exeseal.IsSelfExeCloned() { |
| 513 | // /proc/self/exe is already a cloned binary -- no need to do anything |
| 514 | logrus.Debug("skipping binary cloning -- /proc/self/exe is already cloned!") |
| 515 | // We don't need to use /proc/thread-self here because the exe mm of a |
| 516 | // thread-group is guaranteed to be the same for all threads by |
| 517 | // definition. This lets us avoid having to do runtime.LockOSThread. |
| 518 | exePath = "/proc/self/exe" |
| 519 | } else { |
| 520 | var err error |
| 521 | safeExe, err = exeseal.CloneSelfExe(c.stateDir) |
| 522 | if err != nil { |
| 523 | return nil, fmt.Errorf("unable to create safe /proc/self/exe clone for runc init: %w", err) |
| 524 | } |
| 525 | exePath = "/proc/self/fd/" + strconv.Itoa(int(safeExe.Fd())) |
| 526 | p.clonedExes = append(p.clonedExes, safeExe) |
| 527 | logrus.Debug("runc exeseal: using /proc/self/exe clone") // used for tests |
| 528 | } |
| 529 | |
| 530 | cmd := exec.Command(exePath, "init") |
| 531 | // Theoretically, exec.Command can set cmd.Err. Practically, this |
| 532 | // should never happen (Linux, Go <= 1.26, exePath is absolute), |
| 533 | // but in the unlikely case it just did, let's fail early. |
| 534 | if cmd.Err != nil { |
| 535 | return nil, fmt.Errorf("exec.Command: %w", cmd.Err) |
| 536 | } |
| 537 | cmd.Args[0] = os.Args[0] |
| 538 | cmd.Stdin = p.Stdin |
| 539 | cmd.Stdout = p.Stdout |
| 540 | cmd.Stderr = p.Stderr |
| 541 | cmd.Dir = c.config.Rootfs |
| 542 | if cmd.SysProcAttr == nil { |
| 543 | cmd.SysProcAttr = &unix.SysProcAttr{} |
| 544 | } |
| 545 | cmd.Env = append(cmd.Env, "GOMAXPROCS="+os.Getenv("GOMAXPROCS")) |
| 546 | cmd.ExtraFiles = append(cmd.ExtraFiles, p.ExtraFiles...) |
| 547 | if p.ConsoleSocket != nil { |
| 548 | cmd.ExtraFiles = append(cmd.ExtraFiles, p.ConsoleSocket) |
| 549 | cmd.Env = append(cmd.Env, |
| 550 | "_LIBCONTAINER_CONSOLE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1), |
| 551 | ) |
| 552 | } |
| 553 |
no test coverage detected