fusefronted: reject GETXATTR "security.capability"
Unless we are mounted with -suid, we can reject these requests, and gain back some lost speed. Closes https://github.com/rfjakob/gocryptfs/issues/515
This commit is contained in:
parent
c943ed32aa
commit
6697ffd6e2
@ -64,7 +64,8 @@ v1.7.1 577 1100 8.3 4.2 0.9 2.0 go1.14.2, Linux 5.
|
|||||||
v1.7.1-60-gb23f77c 472 1100 12.7 4.2 0.8 2.0
|
v1.7.1-60-gb23f77c 472 1100 12.7 4.2 0.8 2.0
|
||||||
v1.8.0 410 1000 17.5 6.7 5.4 7.8 go1.15.3, Linux 5.8.13
|
v1.8.0 410 1000 17.5 6.7 5.4 7.8 go1.15.3, Linux 5.8.13
|
||||||
v2.0-beta1 387 1100 36.2 14.4 12.8 19.3
|
v2.0-beta1 387 1100 36.2 14.4 12.8 19.3
|
||||||
|
v2.0-beta1-5-gc943ed3 417 1000 30.4 12.7 9.9 16.4
|
||||||
|
v2.0-beta1-6 529 1100 17.5 9.0 3.6 9.0
|
||||||
|
|
||||||
Results for EncFS for comparison (benchmark.bash -encfs):
|
Results for EncFS for comparison (benchmark.bash -encfs):
|
||||||
|
|
||||||
|
@ -39,4 +39,9 @@ type Args struct {
|
|||||||
// ExcludeFrom is a list of files from which to read exclusion patterns
|
// ExcludeFrom is a list of files from which to read exclusion patterns
|
||||||
// (with wildcard syntax)
|
// (with wildcard syntax)
|
||||||
ExcludeFrom []string
|
ExcludeFrom []string
|
||||||
|
// Suid is true if the filesystem has been mounted with the "-suid" flag.
|
||||||
|
// If it is false, we can ignore the GETXATTR "security.capability" calls,
|
||||||
|
// which are a performance problem for writes. See
|
||||||
|
// https://github.com/rfjakob/gocryptfs/issues/515 for details.
|
||||||
|
Suid bool
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,24 @@ var xattrNameIV = []byte("xattr_name_iv_xx")
|
|||||||
// encrypted original name.
|
// encrypted original name.
|
||||||
var xattrStorePrefix = "user.gocryptfs."
|
var xattrStorePrefix = "user.gocryptfs."
|
||||||
|
|
||||||
|
// We get one read of this xattr for each write -
|
||||||
|
// see https://github.com/rfjakob/gocryptfs/issues/515 for details.
|
||||||
|
var xattrCapability = "security.capability"
|
||||||
|
|
||||||
// GetXAttr - FUSE call. Reads the value of extended attribute "attr".
|
// GetXAttr - FUSE call. Reads the value of extended attribute "attr".
|
||||||
//
|
//
|
||||||
// This function is symlink-safe through Fgetxattr.
|
// This function is symlink-safe through Fgetxattr.
|
||||||
func (n *Node) Getxattr(ctx context.Context, attr string, dest []byte) (uint32, syscall.Errno) {
|
func (n *Node) Getxattr(ctx context.Context, attr string, dest []byte) (uint32, syscall.Errno) {
|
||||||
rn := n.rootNode()
|
rn := n.rootNode()
|
||||||
|
// If we are not mounted with -suid, reading the capability xattr does not
|
||||||
|
// make a lot of sense, so reject the request and gain a massive speedup.
|
||||||
|
// See https://github.com/rfjakob/gocryptfs/issues/515 .
|
||||||
|
if !rn.args.Suid && attr == xattrCapability {
|
||||||
|
// Returning EOPNOTSUPP is what we did till
|
||||||
|
// ca9e912a28b901387e1dbb85f6c531119f2d5ef2 "fusefrontend: drop xattr user namespace restriction"
|
||||||
|
// and it did not cause trouble. Seems cleaner than saying ENODATA.
|
||||||
|
return 0, syscall.EOPNOTSUPP
|
||||||
|
}
|
||||||
cAttr := rn.encryptXattrName(attr)
|
cAttr := rn.encryptXattrName(attr)
|
||||||
cData, errno := n.getXAttr(cAttr)
|
cData, errno := n.getXAttr(cAttr)
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
|
BIN
internal/syscallcompat/mem.prof
Normal file
BIN
internal/syscallcompat/mem.prof
Normal file
Binary file not shown.
BIN
internal/syscallcompat/mem2.prof
Normal file
BIN
internal/syscallcompat/mem2.prof
Normal file
Binary file not shown.
6
internal/syscallcompat/new.txt
Normal file
6
internal/syscallcompat/new.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
goos: linux
|
||||||
|
goarch: amd64
|
||||||
|
pkg: github.com/rfjakob/gocryptfs/internal/syscallcompat
|
||||||
|
BenchmarkLgetxattr-4 594607 1799 ns/op
|
||||||
|
PASS
|
||||||
|
ok github.com/rfjakob/gocryptfs/internal/syscallcompat 1.108s
|
6
internal/syscallcompat/old.txt
Normal file
6
internal/syscallcompat/old.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
goos: linux
|
||||||
|
goarch: amd64
|
||||||
|
pkg: github.com/rfjakob/gocryptfs/internal/syscallcompat
|
||||||
|
BenchmarkLgetxattr-4 77743 15183 ns/op
|
||||||
|
PASS
|
||||||
|
ok github.com/rfjakob/gocryptfs/internal/syscallcompat 1.360s
|
BIN
internal/syscallcompat/prof
Normal file
BIN
internal/syscallcompat/prof
Normal file
Binary file not shown.
BIN
internal/syscallcompat/prof2
Normal file
BIN
internal/syscallcompat/prof2
Normal file
Binary file not shown.
1
mount.go
1
mount.go
@ -266,6 +266,7 @@ func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys f
|
|||||||
Exclude: args.exclude,
|
Exclude: args.exclude,
|
||||||
ExcludeWildcard: args.excludeWildcard,
|
ExcludeWildcard: args.excludeWildcard,
|
||||||
ExcludeFrom: args.excludeFrom,
|
ExcludeFrom: args.excludeFrom,
|
||||||
|
Suid: args.suid,
|
||||||
}
|
}
|
||||||
// confFile is nil when "-zerokey" or "-masterkey" was used
|
// confFile is nil when "-zerokey" or "-masterkey" was used
|
||||||
if confFile != nil {
|
if confFile != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user