selinux.go 9.8 KB

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