From 96a8ee0c07c6d1e5ed0da62ad162146c1692cd09 Mon Sep 17 00:00:00 2001 From: zhouhaibing089 Date: Wed, 4 May 2022 09:31:10 -0700 Subject: [PATCH] hasher: hash security.capability attributes (#1994) In Dockerfile, if there is something like: ``` RUN setcap cap_net_raw=+ep /path/to/binary ``` kaniko won't detect that there is a change on file `/path/to/binary` and thus discards this layer. This patch allows the hasher function to actually look at `security.capability` extended attributes. --- pkg/util/util.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pkg/util/util.go b/pkg/util/util.go index 600f3d1bb7..9387dd029c 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -31,6 +31,7 @@ import ( "github.com/minio/highwayhash" "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" ) // Hasher returns a hash function, used in snapshotting to determine if a file has changed @@ -56,6 +57,10 @@ func Hasher() func(string) (string, error) { h.Write([]byte(strconv.FormatUint(uint64(fi.Sys().(*syscall.Stat_t).Gid), 36))) if fi.Mode().IsRegular() { + capability, _ := Lgetxattr(p, "security.capability") + if capability != nil { + h.Write(capability) + } f, err := os.Open(p) if err != nil { return "", err @@ -172,3 +177,28 @@ func Retry(operation retryFunc, retryCount int, initialDelayMilliseconds int) er return err } + +func Lgetxattr(path string, attr string) ([]byte, error) { + // Start with a 128 length byte array + dest := make([]byte, 128) + sz, errno := unix.Lgetxattr(path, attr, dest) + + for errno == unix.ERANGE { + // Buffer too small, use zero-sized buffer to get the actual size + sz, errno = unix.Lgetxattr(path, attr, []byte{}) + if errno != nil { + return nil, errno + } + dest = make([]byte, sz) + sz, errno = unix.Lgetxattr(path, attr, dest) + } + + switch { + case errno == unix.ENODATA: + return nil, nil + case errno != nil: + return nil, errno + } + + return dest[:sz], nil +}