diff options
author | Chong Cai <chongc@google.com> | 2021-03-23 11:04:08 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-03-23 11:06:02 -0700 |
commit | beb11cec7669d029172751e5b4dfe21c0672a25a (patch) | |
tree | 27fad88ce84075d91830aba0069442c2f6ad3efd | |
parent | dc75f08c2ade0c52af190a33766ecc522237e682 (diff) |
Allow FSETXATTR/FGETXATTR host calls for Verity
These host calls are needed for Verity fs to generate/verify hashes.
PiperOrigin-RevId: 364598180
-rw-r--r-- | runsc/cmd/gofer.go | 14 | ||||
-rw-r--r-- | runsc/fsgofer/filter/config.go | 5 | ||||
-rw-r--r-- | runsc/fsgofer/filter/filter.go | 6 | ||||
-rw-r--r-- | runsc/fsgofer/fsgofer.go | 23 | ||||
-rw-r--r-- | runsc/fsgofer/fsgofer_test.go | 26 |
5 files changed, 54 insertions, 20 deletions
diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index d703e4042..4cb0164dd 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -165,8 +165,8 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // Start with root mount, then add any other additional mount as needed. ats := make([]p9.Attacher, 0, len(spec.Mounts)+1) ap, err := fsgofer.NewAttachPoint("/", fsgofer.Config{ - ROMount: spec.Root.Readonly || conf.Overlay, - EnableXattr: conf.Verity, + ROMount: spec.Root.Readonly || conf.Overlay, + EnableVerityXattr: conf.Verity, }) if err != nil { Fatalf("creating attach point: %v", err) @@ -178,9 +178,9 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) for _, m := range spec.Mounts { if specutils.Is9PMount(m) { cfg := fsgofer.Config{ - ROMount: isReadonlyMount(m.Options) || conf.Overlay, - HostUDS: conf.FSGoferHostUDS, - EnableXattr: conf.Verity, + ROMount: isReadonlyMount(m.Options) || conf.Overlay, + HostUDS: conf.FSGoferHostUDS, + EnableVerityXattr: conf.Verity, } ap, err := fsgofer.NewAttachPoint(m.Destination, cfg) if err != nil { @@ -203,6 +203,10 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) filter.InstallUDSFilters() } + if conf.Verity { + filter.InstallXattrFilters() + } + if err := filter.Install(); err != nil { Fatalf("installing seccomp filters: %v", err) } diff --git a/runsc/fsgofer/filter/config.go b/runsc/fsgofer/filter/config.go index fd72414ce..246b7ed3c 100644 --- a/runsc/fsgofer/filter/config.go +++ b/runsc/fsgofer/filter/config.go @@ -247,3 +247,8 @@ var udsSyscalls = seccomp.SyscallRules{ }, }, } + +var xattrSyscalls = seccomp.SyscallRules{ + unix.SYS_FGETXATTR: {}, + unix.SYS_FSETXATTR: {}, +} diff --git a/runsc/fsgofer/filter/filter.go b/runsc/fsgofer/filter/filter.go index 289886720..6c67ee288 100644 --- a/runsc/fsgofer/filter/filter.go +++ b/runsc/fsgofer/filter/filter.go @@ -36,3 +36,9 @@ func InstallUDSFilters() { // Add additional filters required for connecting to the host's sockets. allowedSyscalls.Merge(udsSyscalls) } + +// InstallXattrFilters extends the allowed syscalls to include xattr calls that +// are necessary for Verity enabled file systems. +func InstallXattrFilters() { + allowedSyscalls.Merge(xattrSyscalls) +} diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index 1e80a634d..e04ddda47 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -48,6 +48,14 @@ const ( allowedOpenFlags = unix.O_TRUNC ) +// verityXattrs are the extended attributes used by verity file system. +var verityXattrs = map[string]struct{}{ + "user.merkle.offset": struct{}{}, + "user.merkle.size": struct{}{}, + "user.merkle.childrenOffset": struct{}{}, + "user.merkle.childrenSize": struct{}{}, +} + // join is equivalent to path.Join() but skips path.Clean() which is expensive. func join(parent, child string) string { if child == "." || child == ".." { @@ -67,8 +75,9 @@ type Config struct { // HostUDS signals whether the gofer can mount a host's UDS. HostUDS bool - // enableXattr allows Get/SetXattr for the mounted file systems. - EnableXattr bool + // EnableVerityXattr allows access to extended attributes used by the + // verity file system. + EnableVerityXattr bool } type attachPoint struct { @@ -799,7 +808,10 @@ func (l *localFile) SetAttr(valid p9.SetAttrMask, attr p9.SetAttr) error { } func (l *localFile) GetXattr(name string, size uint64) (string, error) { - if !l.attachPoint.conf.EnableXattr { + if !l.attachPoint.conf.EnableVerityXattr { + return "", unix.EOPNOTSUPP + } + if _, ok := verityXattrs[name]; !ok { return "", unix.EOPNOTSUPP } buffer := make([]byte, size) @@ -810,7 +822,10 @@ func (l *localFile) GetXattr(name string, size uint64) (string, error) { } func (l *localFile) SetXattr(name string, value string, flags uint32) error { - if !l.attachPoint.conf.EnableXattr { + if !l.attachPoint.conf.EnableVerityXattr { + return unix.EOPNOTSUPP + } + if _, ok := verityXattrs[name]; !ok { return unix.EOPNOTSUPP } return unix.Fsetxattr(l.file.FD(), name, []byte(value), int(flags)) diff --git a/runsc/fsgofer/fsgofer_test.go b/runsc/fsgofer/fsgofer_test.go index a5f09f88f..d7e141476 100644 --- a/runsc/fsgofer/fsgofer_test.go +++ b/runsc/fsgofer/fsgofer_test.go @@ -579,20 +579,24 @@ func SetGetXattr(l *localFile, name string, value string) error { return nil } +func TestSetGetDisabledXattr(t *testing.T) { + runCustom(t, []uint32{unix.S_IFREG}, rwConfs, func(t *testing.T, s state) { + name := "user.merkle.offset" + value := "tmp" + err := SetGetXattr(s.file, name, value) + if err == nil { + t.Fatalf("%v: SetGetXattr should have failed", s) + } + }) +} + func TestSetGetXattr(t *testing.T) { - xattrConfs := []Config{{ROMount: false, EnableXattr: false}, {ROMount: false, EnableXattr: true}} - runCustom(t, []uint32{unix.S_IFREG}, xattrConfs, func(t *testing.T, s state) { - name := "user.test" + runCustom(t, []uint32{unix.S_IFREG}, []Config{{ROMount: false, EnableVerityXattr: true}}, func(t *testing.T, s state) { + name := "user.merkle.offset" value := "tmp" err := SetGetXattr(s.file, name, value) - if s.conf.EnableXattr { - if err != nil { - t.Fatalf("%v: SetGetXattr failed, err: %v", s, err) - } - } else { - if err == nil { - t.Fatalf("%v: SetGetXattr should have failed", s) - } + if err != nil { + t.Fatalf("%v: SetGetXattr failed, err: %v", s, err) } }) } |