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