selinux.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package selinux
  2. import (
  3. "github.com/pkg/errors"
  4. )
  5. const (
  6. // Enforcing constant indicate SELinux is in enforcing mode
  7. Enforcing = 1
  8. // Permissive constant to indicate SELinux is in permissive mode
  9. Permissive = 0
  10. // Disabled constant to indicate SELinux is disabled
  11. Disabled = -1
  12. // maxCategory is the maximum number of categories used within containers
  13. maxCategory = 1024
  14. // DefaultCategoryRange is the upper bound on the category range
  15. DefaultCategoryRange = uint32(maxCategory)
  16. )
  17. var (
  18. // ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
  19. ErrMCSAlreadyExists = errors.New("MCS label already exists")
  20. // ErrEmptyPath is returned when an empty path has been specified.
  21. ErrEmptyPath = errors.New("empty path")
  22. // InvalidLabel is returned when an invalid label is specified.
  23. InvalidLabel = errors.New("Invalid Label")
  24. // ErrIncomparable is returned two levels are not comparable
  25. ErrIncomparable = errors.New("incomparable levels")
  26. // ErrLevelSyntax is returned when a sensitivity or category do not have correct syntax in a level
  27. ErrLevelSyntax = errors.New("invalid level syntax")
  28. // ErrContextMissing is returned if a requested context is not found in a file.
  29. ErrContextMissing = errors.New("context does not have a match")
  30. // ErrVerifierNil is returned when a context verifier function is nil.
  31. ErrVerifierNil = errors.New("verifier function is nil")
  32. // CategoryRange allows the upper bound on the category range to be adjusted
  33. CategoryRange = DefaultCategoryRange
  34. )
  35. // Context is a representation of the SELinux label broken into 4 parts
  36. type Context map[string]string
  37. // SetDisabled disables SELinux support for the package
  38. func SetDisabled() {
  39. setDisabled()
  40. }
  41. // GetEnabled returns whether SELinux is currently enabled.
  42. func GetEnabled() bool {
  43. return getEnabled()
  44. }
  45. // ClassIndex returns the int index for an object class in the loaded policy,
  46. // or -1 and an error
  47. func ClassIndex(class string) (int, error) {
  48. return classIndex(class)
  49. }
  50. // SetFileLabel sets the SELinux label for this path or returns an error.
  51. func SetFileLabel(fpath string, label string) error {
  52. return setFileLabel(fpath, label)
  53. }
  54. // FileLabel returns the SELinux label for this path or returns an error.
  55. func FileLabel(fpath string) (string, error) {
  56. return fileLabel(fpath)
  57. }
  58. // SetFSCreateLabel tells the kernel what label to use for all file system objects
  59. // created by this task.
  60. // Set the label to an empty string to return to the default label. Calls to SetFSCreateLabel
  61. // should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until file system
  62. // objects created by this task are finished to guarantee another goroutine does not migrate
  63. // to the current thread before execution is complete.
  64. func SetFSCreateLabel(label string) error {
  65. return setFSCreateLabel(label)
  66. }
  67. // FSCreateLabel returns the default label the kernel which the kernel is using
  68. // for file system objects created by this task. "" indicates default.
  69. func FSCreateLabel() (string, error) {
  70. return fsCreateLabel()
  71. }
  72. // CurrentLabel returns the SELinux label of the current process thread, or an error.
  73. func CurrentLabel() (string, error) {
  74. return currentLabel()
  75. }
  76. // PidLabel returns the SELinux label of the given pid, or an error.
  77. func PidLabel(pid int) (string, error) {
  78. return pidLabel(pid)
  79. }
  80. // ExecLabel returns the SELinux label that the kernel will use for any programs
  81. // that are executed by the current process thread, or an error.
  82. func ExecLabel() (string, error) {
  83. return execLabel()
  84. }
  85. // CanonicalizeContext takes a context string and writes it to the kernel
  86. // the function then returns the context that the kernel will use. Use this
  87. // function to check if two contexts are equivalent
  88. func CanonicalizeContext(val string) (string, error) {
  89. return canonicalizeContext(val)
  90. }
  91. // ComputeCreateContext requests the type transition from source to target for
  92. // class from the kernel.
  93. func ComputeCreateContext(source string, target string, class string) (string, error) {
  94. return computeCreateContext(source, target, class)
  95. }
  96. // CalculateGlbLub computes the glb (greatest lower bound) and lub (least upper bound)
  97. // of a source and target range.
  98. // The glblub is calculated as the greater of the low sensitivities and
  99. // the lower of the high sensitivities and the and of each category bitset.
  100. func CalculateGlbLub(sourceRange, targetRange string) (string, error) {
  101. return calculateGlbLub(sourceRange, targetRange)
  102. }
  103. // SetExecLabel sets the SELinux label that the kernel will use for any programs
  104. // that are executed by the current process thread, or an error. Calls to SetExecLabel
  105. // should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until execution
  106. // of the program is finished to guarantee another goroutine does not migrate to the current
  107. // thread before execution is complete.
  108. func SetExecLabel(label string) error {
  109. return setExecLabel(label)
  110. }
  111. // SetTaskLabel sets the SELinux label for the current thread, or an error.
  112. // This requires the dyntransition permission. Calls to SetTaskLabel should
  113. // be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() to guarantee
  114. // the current thread does not run in a new mislabeled thread.
  115. func SetTaskLabel(label string) error {
  116. return setTaskLabel(label)
  117. }
  118. // SetSocketLabel takes a process label and tells the kernel to assign the
  119. // label to the next socket that gets created. Calls to SetSocketLabel
  120. // should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until
  121. // the the socket is created to guarantee another goroutine does not migrate
  122. // to the current thread before execution is complete.
  123. func SetSocketLabel(label string) error {
  124. return setSocketLabel(label)
  125. }
  126. // SocketLabel retrieves the current socket label setting
  127. func SocketLabel() (string, error) {
  128. return socketLabel()
  129. }
  130. // PeerLabel retrieves the label of the client on the other side of a socket
  131. func PeerLabel(fd uintptr) (string, error) {
  132. return peerLabel(fd)
  133. }
  134. // SetKeyLabel takes a process label and tells the kernel to assign the
  135. // label to the next kernel keyring that gets created. Calls to SetKeyLabel
  136. // should be wrapped in runtime.LockOSThread()/runtime.UnlockOSThread() until
  137. // the kernel keyring is created to guarantee another goroutine does not migrate
  138. // to the current thread before execution is complete.
  139. func SetKeyLabel(label string) error {
  140. return setKeyLabel(label)
  141. }
  142. // KeyLabel retrieves the current kernel keyring label setting
  143. func KeyLabel() (string, error) {
  144. return keyLabel()
  145. }
  146. // Get returns the Context as a string
  147. func (c Context) Get() string {
  148. return c.get()
  149. }
  150. // NewContext creates a new Context struct from the specified label
  151. func NewContext(label string) (Context, error) {
  152. return newContext(label)
  153. }
  154. // ClearLabels clears all reserved labels
  155. func ClearLabels() {
  156. clearLabels()
  157. }
  158. // ReserveLabel reserves the MLS/MCS level component of the specified label
  159. func ReserveLabel(label string) {
  160. reserveLabel(label)
  161. }
  162. // EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
  163. func EnforceMode() int {
  164. return enforceMode()
  165. }
  166. // SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
  167. // Disabled is not valid, since this needs to be set at boot time.
  168. func SetEnforceMode(mode int) error {
  169. return setEnforceMode(mode)
  170. }
  171. // DefaultEnforceMode returns the systems default SELinux mode Enforcing,
  172. // Permissive or Disabled. Note this is is just the default at boot time.
  173. // EnforceMode tells you the systems current mode.
  174. func DefaultEnforceMode() int {
  175. return defaultEnforceMode()
  176. }
  177. // ReleaseLabel un-reserves the MLS/MCS Level field of the specified label,
  178. // allowing it to be used by another process.
  179. func ReleaseLabel(label string) {
  180. releaseLabel(label)
  181. }
  182. // ROFileLabel returns the specified SELinux readonly file label
  183. func ROFileLabel() string {
  184. return roFileLabel()
  185. }
  186. // KVMContainerLabels returns the default processLabel and mountLabel to be used
  187. // for kvm containers by the calling process.
  188. func KVMContainerLabels() (string, string) {
  189. return kvmContainerLabels()
  190. }
  191. // InitContainerLabels returns the default processLabel and file labels to be
  192. // used for containers running an init system like systemd by the calling process.
  193. func InitContainerLabels() (string, string) {
  194. return initContainerLabels()
  195. }
  196. // ContainerLabels returns an allocated processLabel and fileLabel to be used for
  197. // container labeling by the calling process.
  198. func ContainerLabels() (processLabel string, fileLabel string) {
  199. return containerLabels()
  200. }
  201. // SecurityCheckContext validates that the SELinux label is understood by the kernel
  202. func SecurityCheckContext(val string) error {
  203. return securityCheckContext(val)
  204. }
  205. // CopyLevel returns a label with the MLS/MCS level from src label replaced on
  206. // the dest label.
  207. func CopyLevel(src, dest string) (string, error) {
  208. return copyLevel(src, dest)
  209. }
  210. // Chcon changes the fpath file object to the SELinux label label.
  211. // If fpath is a directory and recurse is true, then Chcon walks the
  212. // directory tree setting the label.
  213. func Chcon(fpath string, label string, recurse bool) error {
  214. return chcon(fpath, label, recurse)
  215. }
  216. // DupSecOpt takes an SELinux process label and returns security options that
  217. // can be used to set the SELinux Type and Level for future container processes.
  218. func DupSecOpt(src string) ([]string, error) {
  219. return dupSecOpt(src)
  220. }
  221. // DisableSecOpt returns a security opt that can be used to disable SELinux
  222. // labeling support for future container processes.
  223. func DisableSecOpt() []string {
  224. return disableSecOpt()
  225. }
  226. // GetDefaultContextWithLevel gets a single context for the specified SELinux user
  227. // identity that is reachable from the specified scon context. The context is based
  228. // on the per-user /etc/selinux/{SELINUXTYPE}/contexts/users/<username> if it exists,
  229. // and falls back to the global /etc/selinux/{SELINUXTYPE}/contexts/default_contexts
  230. // file.
  231. func GetDefaultContextWithLevel(user, level, scon string) (string, error) {
  232. return getDefaultContextWithLevel(user, level, scon)
  233. }
  234. // PrivContainerMountLabel returns mount label for privileged containers
  235. func PrivContainerMountLabel() string {
  236. return privContainerMountLabel
  237. }