utils.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package execdriver
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/docker/docker/utils"
  6. "github.com/syndtr/gocapability/capability"
  7. )
  8. var capabilityList = Capabilities{
  9. {Key: "SETPCAP", Value: capability.CAP_SETPCAP},
  10. {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE},
  11. {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO},
  12. {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT},
  13. {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN},
  14. {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE},
  15. {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE},
  16. {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME},
  17. {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG},
  18. {Key: "MKNOD", Value: capability.CAP_MKNOD},
  19. {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE},
  20. {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL},
  21. {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE},
  22. {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN},
  23. {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN},
  24. {Key: "SYSLOG", Value: capability.CAP_SYSLOG},
  25. {Key: "CHOWN", Value: capability.CAP_CHOWN},
  26. {Key: "NET_RAW", Value: capability.CAP_NET_RAW},
  27. {Key: "DAC_OVERRIDE", Value: capability.CAP_DAC_OVERRIDE},
  28. {Key: "FOWNER", Value: capability.CAP_FOWNER},
  29. {Key: "DAC_READ_SEARCH", Value: capability.CAP_DAC_READ_SEARCH},
  30. {Key: "FSETID", Value: capability.CAP_FSETID},
  31. {Key: "KILL", Value: capability.CAP_KILL},
  32. {Key: "SETGID", Value: capability.CAP_SETGID},
  33. {Key: "SETUID", Value: capability.CAP_SETUID},
  34. {Key: "LINUX_IMMUTABLE", Value: capability.CAP_LINUX_IMMUTABLE},
  35. {Key: "NET_BIND_SERVICE", Value: capability.CAP_NET_BIND_SERVICE},
  36. {Key: "NET_BROADCAST", Value: capability.CAP_NET_BROADCAST},
  37. {Key: "IPC_LOCK", Value: capability.CAP_IPC_LOCK},
  38. {Key: "IPC_OWNER", Value: capability.CAP_IPC_OWNER},
  39. {Key: "SYS_CHROOT", Value: capability.CAP_SYS_CHROOT},
  40. {Key: "SYS_PTRACE", Value: capability.CAP_SYS_PTRACE},
  41. {Key: "SYS_BOOT", Value: capability.CAP_SYS_BOOT},
  42. {Key: "LEASE", Value: capability.CAP_LEASE},
  43. {Key: "SETFCAP", Value: capability.CAP_SETFCAP},
  44. {Key: "WAKE_ALARM", Value: capability.CAP_WAKE_ALARM},
  45. {Key: "BLOCK_SUSPEND", Value: capability.CAP_BLOCK_SUSPEND},
  46. }
  47. type (
  48. CapabilityMapping struct {
  49. Key string `json:"key,omitempty"`
  50. Value capability.Cap `json:"value,omitempty"`
  51. }
  52. Capabilities []*CapabilityMapping
  53. )
  54. func (c *CapabilityMapping) String() string {
  55. return c.Key
  56. }
  57. func GetCapability(key string) *CapabilityMapping {
  58. for _, capp := range capabilityList {
  59. if capp.Key == key {
  60. cpy := *capp
  61. return &cpy
  62. }
  63. }
  64. return nil
  65. }
  66. func GetAllCapabilities() []string {
  67. output := make([]string, len(capabilityList))
  68. for i, capability := range capabilityList {
  69. output[i] = capability.String()
  70. }
  71. return output
  72. }
  73. func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
  74. var (
  75. newCaps []string
  76. allCaps = GetAllCapabilities()
  77. )
  78. // look for invalid cap in the drop list
  79. for _, cap := range drops {
  80. if strings.ToLower(cap) == "all" {
  81. continue
  82. }
  83. if !utils.StringsContainsNoCase(allCaps, cap) {
  84. return nil, fmt.Errorf("Unknown capability drop: %q", cap)
  85. }
  86. }
  87. // handle --cap-add=all
  88. if utils.StringsContainsNoCase(adds, "all") {
  89. basics = allCaps
  90. }
  91. if !utils.StringsContainsNoCase(drops, "all") {
  92. for _, cap := range basics {
  93. // skip `all` aready handled above
  94. if strings.ToLower(cap) == "all" {
  95. continue
  96. }
  97. // if we don't drop `all`, add back all the non-dropped caps
  98. if !utils.StringsContainsNoCase(drops, cap) {
  99. newCaps = append(newCaps, strings.ToUpper(cap))
  100. }
  101. }
  102. }
  103. for _, cap := range adds {
  104. // skip `all` aready handled above
  105. if strings.ToLower(cap) == "all" {
  106. continue
  107. }
  108. if !utils.StringsContainsNoCase(allCaps, cap) {
  109. return nil, fmt.Errorf("Unknown capability to add: %q", cap)
  110. }
  111. // add cap if not already in the list
  112. if !utils.StringsContainsNoCase(newCaps, cap) {
  113. newCaps = append(newCaps, strings.ToUpper(cap))
  114. }
  115. }
  116. return newCaps, nil
  117. }