Skip to content

Commit d7e1f52

Browse files
njhaleopenshift-cherrypick-robot
authored and
openshift-cherrypick-robot
committedJun 7, 2021
fix(containerd): drop xattrs during unpack
On some systems, creating files with certain extended attributes is a restricted operation -- e.g. "security.compatibility" on SELinux -- and causes bundle and index unpacking to fail for unprivileged users. To fix this, we drop all xattrs from unpacked files before writing them. Signed-off-by: Nick Hale <[email protected]>
1 parent 5ccabf9 commit d7e1f52

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed
 

‎pkg/image/containerdregistry/registry.go

+33-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"io"
1010
"os"
1111
"regexp"
12+
"strings"
1213
"time"
1314

1415
"github.com/containerd/containerd/archive"
@@ -205,7 +206,9 @@ func (r *Registry) unpackLayer(ctx context.Context, layer ocispec.Descriptor, di
205206
if err != nil {
206207
return err
207208
}
208-
_, err = archive.Apply(ctx, dir, decompressed, archive.WithFilter(adjustPerms))
209+
210+
filters := filterList{adjustPerms, dropXattrs}
211+
_, err = archive.Apply(ctx, dir, decompressed, archive.WithFilter(filters.and))
209212

210213
return err
211214
}
@@ -217,6 +220,19 @@ func ensureNamespace(ctx context.Context) context.Context {
217220
return ctx
218221
}
219222

223+
type filterList []archive.Filter
224+
225+
func (f filterList) and(h *tar.Header) (bool, error) {
226+
for _, filter := range f {
227+
ok, err := filter(h)
228+
if !ok || err != nil {
229+
return ok, err
230+
}
231+
}
232+
233+
return true, nil
234+
}
235+
220236
func adjustPerms(h *tar.Header) (bool, error) {
221237
h.Uid = os.Getuid()
222238
h.Gid = os.Getgid()
@@ -229,3 +245,19 @@ func adjustPerms(h *tar.Header) (bool, error) {
229245

230246
return true, nil
231247
}
248+
249+
// paxSchilyXattr contains the key prefix for xattrs stored in PAXRecords (see https://golang.org/src/archive/tar/common.go for more details).
250+
const paxSchilyXattr = "SCHILY.xattr."
251+
252+
// dropXattrs removes all xattrs from a Header.
253+
// This is useful for unpacking on systems where writing certain xattrs is a restricted operation; e.g. "security.capability" on SELinux.
254+
func dropXattrs(h *tar.Header) (bool, error) {
255+
h.Xattrs = nil // Deprecated, but still in use, clear anyway.
256+
for key := range h.PAXRecords {
257+
if strings.HasPrefix(key, paxSchilyXattr) { // Xattrs are stored under keys with the "Schilly.xattr." prefix.
258+
delete(h.PAXRecords, key)
259+
}
260+
}
261+
262+
return true, nil
263+
}

0 commit comments

Comments
 (0)
Please sign in to comment.