9
9
"io"
10
10
"os"
11
11
"regexp"
12
+ "strings"
12
13
"time"
13
14
14
15
"github.com/containerd/containerd/archive"
@@ -205,7 +206,9 @@ func (r *Registry) unpackLayer(ctx context.Context, layer ocispec.Descriptor, di
205
206
if err != nil {
206
207
return err
207
208
}
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 ))
209
212
210
213
return err
211
214
}
@@ -217,6 +220,19 @@ func ensureNamespace(ctx context.Context) context.Context {
217
220
return ctx
218
221
}
219
222
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
+
220
236
func adjustPerms (h * tar.Header ) (bool , error ) {
221
237
h .Uid = os .Getuid ()
222
238
h .Gid = os .Getgid ()
@@ -229,3 +245,19 @@ func adjustPerms(h *tar.Header) (bool, error) {
229
245
230
246
return true , nil
231
247
}
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