setns_init_linux.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. if err := label.SetKeyLabel(l.config.ProcessLabel); err != nil {
  30. return err
  31. }
  32. defer label.SetKeyLabel("")
  33. // Do not inherit the parent's session keyring.
  34. if _, err := keys.JoinSessionKeyring(l.getSessionRingName()); err != nil {
  35. // Same justification as in standart_init_linux.go as to why we
  36. // don't bail on ENOSYS.
  37. //
  38. // TODO(cyphar): And we should have logging here too.
  39. if errors.Cause(err) != unix.ENOSYS {
  40. return errors.Wrap(err, "join session keyring")
  41. }
  42. }
  43. }
  44. if l.config.CreateConsole {
  45. if err := setupConsole(l.consoleSocket, l.config, false); err != nil {
  46. return err
  47. }
  48. if err := system.Setctty(); err != nil {
  49. return err
  50. }
  51. }
  52. if l.config.NoNewPrivileges {
  53. if err := unix.Prctl(unix.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil {
  54. return err
  55. }
  56. }
  57. if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil {
  58. return err
  59. }
  60. defer label.SetProcessLabel("")
  61. // Without NoNewPrivileges seccomp is a privileged operation, so we need to
  62. // do this before dropping capabilities; otherwise do it as late as possible
  63. // just before execve so as few syscalls take place after it as possible.
  64. if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges {
  65. if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
  66. return err
  67. }
  68. }
  69. if err := finalizeNamespace(l.config); err != nil {
  70. return err
  71. }
  72. if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil {
  73. return err
  74. }
  75. // Set seccomp as close to execve as possible, so as few syscalls take
  76. // place afterward (reducing the amount of syscalls that users need to
  77. // enable in their seccomp profiles).
  78. if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges {
  79. if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil {
  80. return newSystemErrorWithCause(err, "init seccomp")
  81. }
  82. }
  83. return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
  84. }