selinux.go 10 KB

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