Skip to content

Commit

Permalink
hasher: hash security.capability attributes (#1994)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
zhouhaibing089 authored May 4, 2022
1 parent 76a54a0 commit 96a8ee0
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")

This comment has been minimized.

Copy link
@gabyx

gabyx May 5, 2022

Contributor

@zhouhaibing089: Do you know why here Symlinks are not handled?
Where is the place where Symlink Content (the pointed path) is handled?
This answer would greatly improve my understanding of the Symlinkbug: #1944

This comment has been minimized.

Copy link
@zhouhaibing089

zhouhaibing089 May 9, 2022

Author Contributor

I'll have to check it out on what happens if I run setcap on a symbol link file (e.g, does setcap follow the symbol link?).

This comment has been minimized.

Copy link
@zhouhaibing089

zhouhaibing089 May 9, 2022

Author Contributor

Here is what I tried:

# ls -alh /bin/mybash 
lrwxrwxrwx 1 root root 9 May  9 03:54 /bin/mybash -> /bin/bash
# setcap cap_net_raw+ep /bin/mybash
Failed to set capabilities on file `/bin/mybash' (Invalid argument)
The value of the capability argument is not permitted for a file. Or the file is not a regular (non-symlink) file

I have /bin/mybash symlinked to /bin/bash, and then try with setcap cap_net_raw+ep /bin/mybash. The result is that setcap failed with an error message saying that symlink can't be set with capabilities.

In summary, Lgetxattr should work fine, as symlinks are not supported for security.capability attribute anyway.

This comment has been minimized.

Copy link
@gabyx

gabyx May 9, 2022

Contributor

Ah the question was more just too know, why the content of any symlink is not handled in the hasher. Thanks anyway to check the cap for symlinks.

if capability != nil {
h.Write(capability)
}
f, err := os.Open(p)
if err != nil {
return "", err
Expand Down Expand Up @@ -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
}

0 comments on commit 96a8ee0

Please sign in to comment.