capabilities_linux.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // +build linux
  2. package libcontainer
  3. import (
  4. "fmt"
  5. "os"
  6. "strings"
  7. "github.com/syndtr/gocapability/capability"
  8. )
  9. const allCapabilityTypes = capability.CAPS | capability.BOUNDS
  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 newCapWhitelist(caps []string) (*whitelist, error) {
  27. l := []capability.Cap{}
  28. for _, c := range caps {
  29. v, ok := capabilityMap[c]
  30. if !ok {
  31. return nil, fmt.Errorf("unknown capability %q", c)
  32. }
  33. l = append(l, v)
  34. }
  35. pid, err := capability.NewPid(os.Getpid())
  36. if err != nil {
  37. return nil, err
  38. }
  39. return &whitelist{
  40. keep: l,
  41. pid: pid,
  42. }, nil
  43. }
  44. type whitelist struct {
  45. pid capability.Capabilities
  46. keep []capability.Cap
  47. }
  48. // dropBoundingSet drops the capability bounding set to those specified in the whitelist.
  49. func (w *whitelist) dropBoundingSet() error {
  50. w.pid.Clear(capability.BOUNDS)
  51. w.pid.Set(capability.BOUNDS, w.keep...)
  52. return w.pid.Apply(capability.BOUNDS)
  53. }
  54. // drop drops all capabilities for the current process except those specified in the whitelist.
  55. func (w *whitelist) drop() error {
  56. w.pid.Clear(allCapabilityTypes)
  57. w.pid.Set(allCapabilityTypes, w.keep...)
  58. return w.pid.Apply(allCapabilityTypes)
  59. }