capabilities_linux.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // +build linux
  2. package libcontainer
  3. import (
  4. "fmt"
  5. "strings"
  6. "github.com/opencontainers/runc/libcontainer/configs"
  7. "github.com/syndtr/gocapability/capability"
  8. )
  9. const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS
  10. var capabilityMap map[string]capability.Cap
  11. func init() {
  12. capabilityMap = make(map[string]capability.Cap)
  13. last := capability.CAP_LAST_CAP
  14. // workaround for RHEL6 which has no /proc/sys/kernel/cap_last_cap
  15. if last == capability.Cap(63) {
  16. last = capability.CAP_BLOCK_SUSPEND
  17. }
  18. for _, cap := range capability.List() {
  19. if cap > last {
  20. continue
  21. }
  22. capKey := fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String()))
  23. capabilityMap[capKey] = cap
  24. }
  25. }
  26. func newContainerCapList(capConfig *configs.Capabilities) (*containerCapabilities, error) {
  27. bounding := []capability.Cap{}
  28. for _, c := range capConfig.Bounding {
  29. v, ok := capabilityMap[c]
  30. if !ok {
  31. return nil, fmt.Errorf("unknown capability %q", c)
  32. }
  33. bounding = append(bounding, v)
  34. }
  35. effective := []capability.Cap{}
  36. for _, c := range capConfig.Effective {
  37. v, ok := capabilityMap[c]
  38. if !ok {
  39. return nil, fmt.Errorf("unknown capability %q", c)
  40. }
  41. effective = append(effective, v)
  42. }
  43. inheritable := []capability.Cap{}
  44. for _, c := range capConfig.Inheritable {
  45. v, ok := capabilityMap[c]
  46. if !ok {
  47. return nil, fmt.Errorf("unknown capability %q", c)
  48. }
  49. inheritable = append(inheritable, v)
  50. }
  51. permitted := []capability.Cap{}
  52. for _, c := range capConfig.Permitted {
  53. v, ok := capabilityMap[c]
  54. if !ok {
  55. return nil, fmt.Errorf("unknown capability %q", c)
  56. }
  57. permitted = append(permitted, v)
  58. }
  59. ambient := []capability.Cap{}
  60. for _, c := range capConfig.Ambient {
  61. v, ok := capabilityMap[c]
  62. if !ok {
  63. return nil, fmt.Errorf("unknown capability %q", c)
  64. }
  65. ambient = append(ambient, v)
  66. }
  67. pid, err := capability.NewPid(0)
  68. if err != nil {
  69. return nil, err
  70. }
  71. return &containerCapabilities{
  72. bounding: bounding,
  73. effective: effective,
  74. inheritable: inheritable,
  75. permitted: permitted,
  76. ambient: ambient,
  77. pid: pid,
  78. }, nil
  79. }
  80. type containerCapabilities struct {
  81. pid capability.Capabilities
  82. bounding []capability.Cap
  83. effective []capability.Cap
  84. inheritable []capability.Cap
  85. permitted []capability.Cap
  86. ambient []capability.Cap
  87. }
  88. // ApplyBoundingSet sets the capability bounding set to those specified in the whitelist.
  89. func (c *containerCapabilities) ApplyBoundingSet() error {
  90. c.pid.Clear(capability.BOUNDS)
  91. c.pid.Set(capability.BOUNDS, c.bounding...)
  92. return c.pid.Apply(capability.BOUNDS)
  93. }
  94. // Apply sets all the capabilities for the current process in the config.
  95. func (c *containerCapabilities) ApplyCaps() error {
  96. c.pid.Clear(allCapabilityTypes)
  97. c.pid.Set(capability.BOUNDS, c.bounding...)
  98. c.pid.Set(capability.PERMITTED, c.permitted...)
  99. c.pid.Set(capability.INHERITABLE, c.inheritable...)
  100. c.pid.Set(capability.EFFECTIVE, c.effective...)
  101. c.pid.Set(capability.AMBIENT, c.ambient...)
  102. return c.pid.Apply(allCapabilityTypes)
  103. }