diff --git a/.bazelversion b/.bazelversion index fd2a018..fae6e3d 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -3.1.0 +4.2.1 diff --git a/cmd/xattr.go b/cmd/xattr.go index fe3e224..0255ad7 100644 --- a/cmd/xattr.go +++ b/cmd/xattr.go @@ -55,7 +55,7 @@ func NewXATTRCmd() *cobra.Command { } tarWriter := tar.NewWriter(streamOutput) defer tarWriter.Close() - return xattr.Apply(tar.NewReader(streamInput), tarWriter , capabilityMap, labelMap) + return xattr.Apply(tar.NewReader(streamInput), tarWriter, capabilityMap, labelMap) }, } diff --git a/pkg/xattr/testdata/regenerate.sh b/pkg/xattr/testdata/regenerate.sh new file mode 100644 index 0000000..84bd164 --- /dev/null +++ b/pkg/xattr/testdata/regenerate.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +TMPDIR=$(mktemp -d) +trap 'rm -rf "${TMPDIR}"' EXIT + +touch ${TMPDIR}/selinux +touch ${TMPDIR}/cap_net_bind_service +touch ${TMPDIR}/cap_chown +touch ${TMPDIR}/cap_sys_ptrace +touch ${TMPDIR}/cap_all +sudo chcon -t user_home_t ${TMPDIR}/selinux + +sudo setcap 'cap_net_bind_service=+ep' ${TMPDIR}/cap_net_bind_service +sudo setcap 'cap_chown=+ep' ${TMPDIR}/cap_chown +sudo setcap 'cap_sys_ptrace=+ep' ${TMPDIR}/cap_sys_ptrace +sudo setcap 'cap_net_bind_service,cap_chown,cap_sys_ptrace=+ep' ${TMPDIR}/cap_all +tar -C ${TMPDIR} --xattrs -cvf xattr.tar . diff --git a/pkg/xattr/testdata/xattr.tar b/pkg/xattr/testdata/xattr.tar index 019cac5..5d61fee 100644 Binary files a/pkg/xattr/testdata/xattr.tar and b/pkg/xattr/testdata/xattr.tar differ diff --git a/pkg/xattr/xattr.go b/pkg/xattr/xattr.go index 74915e2..bea3adc 100644 --- a/pkg/xattr/xattr.go +++ b/pkg/xattr/xattr.go @@ -13,7 +13,9 @@ const ( var cap_empty_bitmask = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} var supported_capabilities = map[string][]byte{ + "cap_chown": {1, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, "cap_net_bind_service": {1, 0, 0, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + "cap_sys_ptrace": {1, 0, 0, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, } func AddCapabilities(pax map[string]string, capabilities []string) error { @@ -37,7 +39,7 @@ func SetSELinuxLabel(pax map[string]string, label string) error { if label == "" { return fmt.Errorf("label must not be empty, but got '%s'", label) } - pax[selinux_header] = fmt.Sprintf("%s\x00",label) + pax[selinux_header] = fmt.Sprintf("%s\x00", label) return nil } diff --git a/pkg/xattr/xattr_test.go b/pkg/xattr/xattr_test.go index 779dab3..158c697 100644 --- a/pkg/xattr/xattr_test.go +++ b/pkg/xattr/xattr_test.go @@ -14,7 +14,7 @@ var g *GomegaWithT func TestSettingSELinuxLabel(t *testing.T) { g = NewGomegaWithT(t) - referenceEntry, err := getHeader("blub") + referenceEntry, err := getHeader("./selinux") g.Expect(err).ToNot(HaveOccurred()) generatedEntry := &tar.Header{Name: "blub"} @@ -43,3 +43,45 @@ func getHeader(name string) (*tar.Header, error) { } return nil, fmt.Errorf("entry %v does not exist", name) } + +func Test_Capabilities(t *testing.T) { + tests := []struct { + name string + entry string + capabilities []string + }{ + { + name: "should set cap_chown", + entry: "./cap_chown", + capabilities: []string{"cap_chown"}, + }, + { + name: "should set cap_net_bind_service", + entry: "./cap_net_bind_service", + capabilities: []string{"cap_net_bind_service"}, + }, + { + name: "should set cap_sys_ptrace", + entry: "./cap_sys_ptrace", + capabilities: []string{"cap_sys_ptrace"}, + }, + { + name: "should set all implemented capabilities", + entry: "./cap_all", + capabilities: []string{"cap_chown", "cap_net_bind_service", "cap_sys_ptrace"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g = NewGomegaWithT(t) + referenceEntry, err := getHeader(tt.entry) + g.Expect(err).ToNot(HaveOccurred()) + + generatedEntry := &tar.Header{Name: "blub"} + + g.Expect(enrichEntry(generatedEntry, map[string][]string{"blub": tt.capabilities}, nil)).To(Succeed()) + + g.Expect(generatedEntry.PAXRecords[capabilities_header]).To(Equal(referenceEntry.PAXRecords[capabilities_header])) + }) + } +}