-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
selinux-policy: adjust kernel permissions for NFS #205
Conversation
When serving files over NFS, the kernel's permissions to access the inode are checked when determining whether the file can be executed by clients. If the kernel lacks permission, then the client will see a permission error and won't be able to execute the program. Work around this by allowing the kernel access to execute mutable files, while denying it permission to execute a new program without transitioning to a new SELinux context. To close off other potential paths to execution, define a transition to a "forbidden" type that is explicitly denied, and deny the use of any object as an entry point to that domain. Signed-off-by: Ben Cressey <[email protected]>
(or (and (eq t1 trusted_s) | ||
(neq t2 forbidden_t)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this so that any rules related to process transitions wouldn't be affected by the presence of MLS categories on the label. Previously it was a blanket "allow this for trusted subjects" and now it is "allow this for trusted subjects, unless the target context is forbidden".
@@ -166,10 +166,28 @@ | |||
; Subjects that must run verified code can execute immutable objects, since | |||
; those are all protected by dm-verity. | |||
(allow verified_s immutable_o (files (execute))) | |||
(allow kernel_t immutable_o (files (execute))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is necessary because kernel_t
dropped out of the verified_s
set.
; Ideally the kernel would also be denied permission to execute mutable | ||
; objects. However, this breaks certain scenarios such as serving files | ||
; over NFS, where the kernel's permissions are checked. | ||
(allow kernel_t mutable_o (file (execute))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the actual fix to the NFS serving issue.
Note that files (execute)
grants both "execute" and "execute_no_trans"; I've moved to the more specific file
here in order to split up those two permissions.
|
||
; Prevent the kernel from executing mutable objects by blocking execution | ||
; unless there's a defined transition. | ||
(neverallow kernel_t mutable_o (file (execute_no_trans))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This prevents execution because of this check in the "no transition" branch.
; Backstop against kernel execution of mutable objects by defining a type | ||
; transition, which is then explicitly disallowed. | ||
(typetransition kernel_t mutable_o process forbidden_t) | ||
(neverallow kernel_t forbidden_t (processes (transform))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This prevents execution because of this check in the "transition" branch.
(neverallow kernel_t forbidden_t (processes (transform))) | ||
|
||
; Block the use of any object as an entry point to the forbidden type. | ||
(neverallow forbidden_t all_o (files (enter))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This causes the next check in the "transition" branch to fail.
; Processes that should never exist. | ||
(type forbidden_t) | ||
(roletype system_r forbidden_t) | ||
(context forbidden (system_u system_r forbidden_t s0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is boilerplate to define the forbidden_t
type.
container_t control_t super_t | ||
forbidden_t)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add forbidden_t
to the set of all subjects (all_s
) since there are a couple "neverallow" rules that should apply to it also.
(typeattributeset verified_s (xor (host_s) ( | ||
runtime_t mount_t api_t init_t kernel_t))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This drops kernel_t
from the verified_s
set, so that we can retain the more restrictive rule:
(neverallow verified_s mutable_o (files (execute)))
Issue number:
Fixes bottlerocket-os/bottlerocket#4116
Description of changes:
When serving files over NFS, the kernel's permissions to access the inode are checked when determining whether the file can be executed by clients. If the kernel lacks permission, then the client will see a permission error and won't be able to execute the program.
Work around this by allowing the kernel access to execute mutable files, while denying it permission to execute a new program without transitioning to a new SELinux context.
To close off other potential paths to execution, define a transition to a "forbidden" type that is explicitly denied, and deny the use of any object as an entry point to that domain.
Testing done:
Verified that the test case in the related issue now passes.
Added a test case to attempt to trigger kernel execution of untrusted code via one of the well-known forms of container escape - installing a new core pattern handler. Confirmed that execution was blocked:
Terms of contribution:
By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.