setns_init_linux.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // +build linux
  2. package libcontainer
  3. import (
  4. "fmt"
  5. "os"
  6. "runtime"
  7. "github.com/opencontainers/runc/libcontainer/apparmor"
  8. "github.com/opencontainers/runc/libcontainer/keys"
  9. "github.com/opencontainers/runc/libcontainer/seccomp"
  10. "github.com/opencontainers/runc/libcontainer/system"
  11. "github.com/opencontainers/selinux/go-selinux/label"
  12. "github.com/pkg/errors"
  13. "golang.org/x/sys/unix"
  14. )
  15. // linuxSetnsInit performs the container's initialization for running a new process
  16. // inside an existing container.
  17. type linuxSetnsInit struct {
  18. pipe *os.File
  19. consoleSocket *os.File
  20. config *initConfig
  21. }
  22. func (l *linuxSetnsInit) getSessionRingName() string {
  23. return fmt.Sprintf("_ses.%s", l.config.ContainerId)
  24. }
  25. func (l *linuxSetnsInit) Init() error {
  26. runtime.LockOSThread()
  27. defer runtime.UnlockOSThread()
  28. if !l.config.Config.NoNewKeyring {
  29. // Do not inherit the parent's session keyring.
  30. if _, err := keys.JoinSessionKeyring(l.getSessionRingName()); err != nil {
  31. // Same justification as in standart_init_linux.go as to why we
  32. // don't bail on ENOSYS.
  33. //
  34. // TODO(cyphar): And we should have logging here too.
  35. if errors.Cause(err) != unix.ENOSYS {
  36. return errors.Wrap(err, "join session keyring")
  37. }
  38. }
  39. }
  40. if l.config.CreateConsole {
  41. if err := setupConsole(l.consoleSocket, l.config, false); err != nil {
  42. return err
  43. }
  44. if err := system.Setctty(); err != nil {
  45. return err
  46. }
  47. }
  48. if l.config.NoNewPrivileges {
  49. if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
  50. return err
  51. }
  52. }
  53. if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
  54. return err
  55. }
  56. defer label.SetProcessLabel("")
  57. // Without NoNewPrivileges seccomp is a privileged operation, so we need to
  58. // do this before dropping capabilities; otherwise do it as late as possible
  59. // just before execve so as few syscalls take place after it as possible.
  60. if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges {
  61. if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
  62. return err
  63. }
  64. }
  65. if err := finalizeNamespace(l.config); err != nil {
  66. return err
  67. }
  68. if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
  69. return err
  70. }
  71. // Set seccomp as close to execve as possible, so as few syscalls take
  72. // place afterward (reducing the amount of syscalls that users need to
  73. // enable in their seccomp profiles).
  74. if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges {
  75. if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
  76. return newSystemErrorWithCause(err, "init seccomp")
  77. }
  78. }
  79. return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
  80. }