aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2020-10-18 21:05:44 +0200
committerJakob Unterwurzacher2020-10-18 21:07:30 +0200
commit6697ffd6e213828ff4cd873cd1d104877096a230 (patch)
treef256f0b720d0472b37c0af08806786d2232e8806
parentc943ed32aaf94a4e60d96c7a513180d29b15a40a (diff)
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
-rw-r--r--Documentation/performance.txt3
-rw-r--r--internal/fusefrontend/args.go5
-rw-r--r--internal/fusefrontend/node_xattr.go13
-rw-r--r--internal/syscallcompat/mem.profbin0 -> 902 bytes
-rw-r--r--internal/syscallcompat/mem2.profbin0 -> 1015 bytes
-rw-r--r--internal/syscallcompat/new.txt6
-rw-r--r--internal/syscallcompat/old.txt6
-rw-r--r--internal/syscallcompat/profbin0 -> 6499 bytes
-rw-r--r--internal/syscallcompat/prof2bin0 -> 5831 bytes
-rw-r--r--mount.go1
10 files changed, 33 insertions, 1 deletions
diff --git a/Documentation/performance.txt b/Documentation/performance.txt
index 4fa2fd9..a724632 100644
--- a/Documentation/performance.txt
+++ b/Documentation/performance.txt
@@ -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.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-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):
diff --git a/internal/fusefrontend/args.go b/internal/fusefrontend/args.go
index 646d6c4..f822650 100644
--- a/internal/fusefrontend/args.go
+++ b/internal/fusefrontend/args.go
@@ -39,4 +39,9 @@ type Args struct {
// ExcludeFrom is a list of files from which to read exclusion patterns
// (with wildcard syntax)
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
}
diff --git a/internal/fusefrontend/node_xattr.go b/internal/fusefrontend/node_xattr.go
index de40915..cbc5804 100644
--- a/internal/fusefrontend/node_xattr.go
+++ b/internal/fusefrontend/node_xattr.go
@@ -18,11 +18,24 @@ var xattrNameIV = []byte("xattr_name_iv_xx")
// encrypted original name.
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".
//
// This function is symlink-safe through Fgetxattr.
func (n *Node) Getxattr(ctx context.Context, attr string, dest []byte) (uint32, syscall.Errno) {
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)
cData, errno := n.getXAttr(cAttr)
if errno != 0 {
diff --git a/internal/syscallcompat/mem.prof b/internal/syscallcompat/mem.prof
new file mode 100644
index 0000000..052fcc6
--- /dev/null
+++ b/internal/syscallcompat/mem.prof
Binary files differ
diff --git a/internal/syscallcompat/mem2.prof b/internal/syscallcompat/mem2.prof
new file mode 100644
index 0000000..e0f73aa
--- /dev/null
+++ b/internal/syscallcompat/mem2.prof
Binary files differ
diff --git a/internal/syscallcompat/new.txt b/internal/syscallcompat/new.txt
new file mode 100644
index 0000000..df3a0ea
--- /dev/null
+++ b/internal/syscallcompat/new.txt
@@ -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
diff --git a/internal/syscallcompat/old.txt b/internal/syscallcompat/old.txt
new file mode 100644
index 0000000..0020b27
--- /dev/null
+++ b/internal/syscallcompat/old.txt
@@ -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
diff --git a/internal/syscallcompat/prof b/internal/syscallcompat/prof
new file mode 100644
index 0000000..4eb4f40
--- /dev/null
+++ b/internal/syscallcompat/prof
Binary files differ
diff --git a/internal/syscallcompat/prof2 b/internal/syscallcompat/prof2
new file mode 100644
index 0000000..54fad10
--- /dev/null
+++ b/internal/syscallcompat/prof2
Binary files differ
diff --git a/mount.go b/mount.go
index f02bc21..39f3f3c 100644
--- a/mount.go
+++ b/mount.go
@@ -266,6 +266,7 @@ func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys f
Exclude: args.exclude,
ExcludeWildcard: args.excludeWildcard,
ExcludeFrom: args.excludeFrom,
+ Suid: args.suid,
}
// confFile is nil when "-zerokey" or "-masterkey" was used
if confFile != nil {