Skip to content
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

Handle filetype field in kubernetes.yaml files #17302

Merged
merged 1 commit into from
Feb 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions libpod/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func ConvertV1PodToYAMLPod(pod *v1.Pod) *YAMLPod {
continue
}
selinuxOpts := ctr.SecurityContext.SELinuxOptions
if selinuxOpts.User == "" && selinuxOpts.Role == "" && selinuxOpts.Type == "" && selinuxOpts.Level == "" {
if selinuxOpts.User == "" && selinuxOpts.Role == "" && selinuxOpts.Type == "" && selinuxOpts.Level == "" && selinuxOpts.FileType == "" {
ctr.SecurityContext.SELinuxOptions = nil
}
}
Expand Down Expand Up @@ -1043,27 +1043,33 @@ func generateKubeSecurityContext(c *Container) (*v1.SecurityContext, bool, error
sc.Capabilities = capabilities
}
var selinuxOpts v1.SELinuxOptions
opts := strings.SplitN(c.config.Spec.Annotations[define.InspectAnnotationLabel], ":", 2)
switch len(opts) {
case 2:
switch opts[0] {
case "type":
selinuxOpts.Type = opts[1]
sc.SELinuxOptions = &selinuxOpts
scHasData = true
case "level":
selinuxOpts.Level = opts[1]
sc.SELinuxOptions = &selinuxOpts
scHasData = true
}
case 1:
if opts[0] == "disable" {
selinuxOpts.Type = "spc_t"
sc.SELinuxOptions = &selinuxOpts
scHasData = true
selinuxHasData := false
for _, label := range strings.Split(c.config.Spec.Annotations[define.InspectAnnotationLabel], ",label=") {
opts := strings.SplitN(label, ":", 2)
switch len(opts) {
case 2:
switch opts[0] {
case "filetype":
selinuxOpts.FileType = opts[1]
selinuxHasData = true
case "type":
selinuxOpts.Type = opts[1]
selinuxHasData = true
case "level":
selinuxOpts.Level = opts[1]
selinuxHasData = true
}
case 1:
if opts[0] == "disable" {
selinuxOpts.Type = "spc_t"
selinuxHasData = true
}
}
}

if selinuxHasData {
sc.SELinuxOptions = &selinuxOpts
scHasData = true
}
if !allowPrivEscalation {
scHasData = true
sc.AllowPrivilegeEscalation = &allowPrivEscalation
Expand Down
3 changes: 3 additions & 0 deletions pkg/k8s.io/api/core/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -4403,6 +4403,9 @@ type SELinuxOptions struct {
// Type is a SELinux type label that applies to the container.
// +optional
Type string `json:"type,omitempty"`
// FileType is a SELinux file type label that applies to the container.
// +optional
FileType string `json:"filetype,omitempty"`
// Level is SELinux level label that applies to the container.
// +optional
Level string `json:"level,omitempty"`
Expand Down
3 changes: 3 additions & 0 deletions pkg/specgen/generate/kube/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,9 @@ func setupSecurityContext(s *specgen.SpecGenerator, securityContext *v1.Security
if seopt.Level != "" {
s.SelinuxOpts = append(s.SelinuxOpts, fmt.Sprintf("level:%s", seopt.Level))
}
if seopt.FileType != "" {
s.SelinuxOpts = append(s.SelinuxOpts, fmt.Sprintf("filetype:%s", seopt.FileType))
}
}
if caps := securityContext.Capabilities; caps != nil {
for _, capability := range caps.Add {
Expand Down
20 changes: 18 additions & 2 deletions test/system/700-play.bats
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ RELABEL="system_u:object_r:container_file_t:s0"
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml

run_podman kube play - < $PODMAN_TMPDIR/test.yaml
if [ -e /usr/sbin/selinuxenabled -a /usr/sbin/selinuxenabled ]; then
if selinux_enabled; then
run ls -Zd $TESTDIR
is "$output" "${RELABEL} $TESTDIR" "selinux relabel should have happened"
fi
Expand All @@ -94,7 +94,7 @@ RELABEL="system_u:object_r:container_file_t:s0"
mkdir -p $TESTDIR
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman play kube $PODMAN_TMPDIR/test.yaml
if [ -e /usr/sbin/selinuxenabled -a /usr/sbin/selinuxenabled ]; then
if selinux_enabled; then
run ls -Zd $TESTDIR
is "$output" "${RELABEL} $TESTDIR" "selinux relabel should have happened"
fi
Expand Down Expand Up @@ -549,3 +549,19 @@ EOF

run_podman kube down $yaml_source
}

@test "podman kube generate filetype" {
YAML=$PODMAN_TMPDIR/test.yml
run_podman create --pod new:pod1 --security-opt label=level:s0:c1,c2 --security-opt label=filetype:usr_t --name test1 $IMAGE true
run_podman kube generate pod1 -f $YAML
run cat $YAML
is "$output" ".*filetype: usr_t" "Generated YAML file should contain filetype usr_t"
run_podman pod rm --force pod1

run_podman kube play $YAML
if selinux_enabled; then
run_podman inspect pod1-test1 --format "{{ .MountLabel }}"
is "$output" "system_u:object_r:usr_t:s0:c1,c2" "Generated container should use filetype usr_t"
fi
run_podman kube down $YAML
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's probably some cleanup missing here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it looks like the initial pod/container used in kube generate need to be removed as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run_podman pod rm --force pod1
Should remove it.

4 changes: 4 additions & 0 deletions test/system/helpers.bash
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,10 @@ function is_aarch64() {
[ "$(uname -m)" == "aarch64" ]
}

function selinux_enabled() {
/usr/sbin/selinuxenabled 2> /dev/null
}

# Returns the OCI runtime *basename* (typically crun or runc). Much as we'd
# love to cache this result, we probably shouldn't.
function podman_runtime() {
Expand Down