From 59165f0f53193f596741b1bc15ade64cb43910ef Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 28 Aug 2022 12:10:25 +0200 Subject: [PATCH 01/20] github ci: add new stable Go versions --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c91ffa2..b410bed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,8 +13,9 @@ jobs: go: - "1.13.x" # Ubuntu 20.04 LTS "focal" - "1.15.x" # Debian 11 "Bullseye" - - "1.16.x" # Golang upstream stable - "1.17.x" # Golang upstream stable + - "1.18.x" # Golang upstream stable + - "1.19.x" # Golang upstream stable # Don't cancel everything when one Go version fails fail-fast: false runs-on: ubuntu-latest From a55b3cc15a6d9bce116a90f33df4bc99d9dd6a10 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 28 Aug 2022 20:31:27 +0200 Subject: [PATCH 02/20] tests/matrix: fix data race in TestConcurrentReadWrite Fixes https://github.com/golang/go/issues/54715 Output was: $ go test ./tests/matrix -run TestConcurrentReadWrite -race test_helpers: warning: testParentDir "/tmp/gocryptfs-test-parent-1026" does not reside on ext4, we will miss failures caused by ino reuse PASS PASS ================== WARNING: DATA RACE Write at 0x00c00038a0e0 by goroutine 63: runtime.racewriterange() :1 +0x29 internal/poll.(*FD).Pread() /usr/local/go/src/internal/poll/fd_unix.go:193 +0x169 os.(*File).pread() /usr/local/go/src/os/file_posix.go:40 +0x335 os.(*File).ReadAt() /usr/local/go/src/os/file.go:136 +0x2de github.com/rfjakob/gocryptfs/v2/tests/matrix.TestConcurrentReadWrite.func1() /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/matrix/concurrency_test.go:40 +0x14b Previous write at 0x00c00038a0e0 by goroutine 61: runtime.racewriterange() :1 +0x29 internal/poll.(*FD).Pread() /usr/local/go/src/internal/poll/fd_unix.go:193 +0x169 os.(*File).pread() /usr/local/go/src/os/file_posix.go:40 +0x335 os.(*File).ReadAt() /usr/local/go/src/os/file.go:136 +0x2de github.com/rfjakob/gocryptfs/v2/tests/matrix.TestConcurrentReadWrite.func1() /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/matrix/concurrency_test.go:40 +0x14b Goroutine 63 (running) created at: github.com/rfjakob/gocryptfs/v2/tests/matrix.TestConcurrentReadWrite() /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/matrix/concurrency_test.go:34 +0x31d testing.tRunner() /usr/local/go/src/testing/testing.go:1446 +0x216 testing.(*T).Run.func1() /usr/local/go/src/testing/testing.go:1493 +0x47 Goroutine 61 (running) created at: github.com/rfjakob/gocryptfs/v2/tests/matrix.TestConcurrentReadWrite() /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/matrix/concurrency_test.go:34 +0x31d testing.tRunner() /usr/local/go/src/testing/testing.go:1446 +0x216 testing.(*T).Run.func1() /usr/local/go/src/testing/testing.go:1493 +0x47 ================== --- FAIL: TestConcurrentReadWrite (0.03s) testing.go:1319: race detected during execution of test FAIL TestMain: matrix[2] = matrix.testcaseMatrix{plaintextnames:false, openssl:"false", aessiv:false, raw64:false, extraArgs:[]string(nil)} failed FAIL github.com/rfjakob/gocryptfs/v2/tests/matrix 0.170s FAIL --- tests/matrix/concurrency_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/matrix/concurrency_test.go b/tests/matrix/concurrency_test.go index d824316..4f060ab 100644 --- a/tests/matrix/concurrency_test.go +++ b/tests/matrix/concurrency_test.go @@ -24,7 +24,6 @@ func TestConcurrentReadWrite(t *testing.T) { } else { f.Close() } - buf := make([]byte, 100) content := []byte("1234567890") threads := 10 loops := 30 @@ -32,6 +31,7 @@ func TestConcurrentReadWrite(t *testing.T) { // Reader thread wg.Add(1) go func() { + buf := make([]byte, 100) fRd, err := os.Open(fn) if err != nil { log.Fatal(err) From f8bd172289789b591b462d0c0da93d61a484704b Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Fri, 21 Oct 2022 22:06:25 +0200 Subject: [PATCH 03/20] Update changelog for v2.3.0 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index cdfac89..14eb2c6 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,11 @@ RM: 2,367 Changelog --------- +#### v2.3.0, 2022-10-21 +* Identical to v2.3, just tagged once more in full semver x.y.z format. This make Go's fetching logic happy, + which ignores v2.3 (without the third digit) completely. + Fixes [#694](https://github.com/rfjakob/gocryptfs/issues/694), [#688](https://github.com/rfjakob/gocryptfs/issues/688). + #### v2.3, 2022-08-28 * Add **`-longnamemax`** flag to `-init` ([#499](https://github.com/rfjakob/gocryptfs/issues/499)). Can be used to work around file or path length restrictions on online storage. From 0ec7ffbfe96887f25feb7fda60b984ea18a42e0f Mon Sep 17 00:00:00 2001 From: Val Date: Wed, 7 Sep 2022 19:17:10 -0400 Subject: [PATCH 04/20] Upgrade go-fuse Ran `go get -u github.com/hanwen/go-fuse/v2@master` to get this diff As pointed out in https://github.com/rfjakob/gocryptfs/issues/595#issuecomment-1222271612, go-fuse was updated with a patch to allow `-reverse` mode on macOS! --- go.mod | 2 +- go.sum | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 754a667..13be3da 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/rfjakob/gocryptfs/v2 go 1.16 require ( - github.com/hanwen/go-fuse/v2 v2.1.1-0.20211219085202-934a183ed914 + github.com/hanwen/go-fuse/v2 v2.1.1-0.20221117175120-915cf5413cde github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd // indirect github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff // indirect diff --git a/go.sum b/go.sum index 4167388..8da7877 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,10 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/hanwen/go-fuse/v2 v2.1.1-0.20211219085202-934a183ed914 h1:hGXMxS1wTE4y+f7iBqFArrJ6X8QozHnEdnVzGZI9Ywc= github.com/hanwen/go-fuse/v2 v2.1.1-0.20211219085202-934a183ed914/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= +github.com/hanwen/go-fuse/v2 v2.1.1-0.20220822120740-58a7e145ff0d h1:nzUYOBVDJ6T1QjPbo7HMdmUlW7+DTV+E64AnNILQYhk= +github.com/hanwen/go-fuse/v2 v2.1.1-0.20220822120740-58a7e145ff0d/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= +github.com/hanwen/go-fuse/v2 v2.1.1-0.20221117175120-915cf5413cde h1:fgTauqHA48CDt+qVQR+PJXqiI9bpYQglMIIi+h/mMts= +github.com/hanwen/go-fuse/v2 v2.1.1-0.20221117175120-915cf5413cde/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 h1:YuDUUFNM21CAbyPOpOP8BicaTD/0klJEKt5p8yuw+uY= github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115/go.mod h1:LadVJg0XuawGk+8L1rYnIED8451UyNxEMdTWCEt5kmU= github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd h1:9GCSedGjMcLZCrusBZuo4tyKLpKUPenUUqi34AkuFmA= From 7ee4c8e9c3b0fb630b48c5940a7faa220ef5e63a Mon Sep 17 00:00:00 2001 From: Christian Stewart Date: Sat, 25 Jun 2022 14:57:38 -0700 Subject: [PATCH 05/20] go.mod: fix jacobsa/crypto build on riscv64 Replace dependency jacobsa/crypto with a fork with support for riscv64. Issue: https://github.com/rfjakob/gocryptfs/issues/666 Upstream PR: https://github.com/jacobsa/crypto/issues/13 Unaddressed on jacobsa/crypto: https://github.com/jacobsa/crypto/pull/14#issuecomment-1182744229 Signed-off-by: Christian Stewart --- README.md | 2 +- go.mod | 9 ++------- go.sum | 21 +++++++++------------ internal/siv_aead/correctness_test.go | 2 +- internal/siv_aead/siv_aead.go | 4 ++-- internal/speed/speed.go | 2 +- 6 files changed, 16 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 14eb2c6..a896133 100644 --- a/README.md +++ b/README.md @@ -585,7 +585,7 @@ Changelog * **Add reverse mode ([#19](https://github.com/rfjakob/gocryptfs/issues/19))** * AES-SIV (RFC5297) encryption to implement deterministic encryption securely. Uses the excellent - [jacobsa/crypto](https://github.com/jacobsa/crypto) library. + [jacobsa/crypto](https://github.com/aperturerobotics/jacobsa-crypto) library. The corresponding feature flag is called `AESSIV`. * New command-line options: `-reverse`, `-aessiv` * Filesystems using reverse mode can only be mounted with gocryptfs v1.1 diff --git a/go.mod b/go.mod index 13be3da..73eabee 100644 --- a/go.mod +++ b/go.mod @@ -3,18 +3,13 @@ module github.com/rfjakob/gocryptfs/v2 go 1.16 require ( + github.com/aperturerobotics/jacobsa-crypto v1.0.0 github.com/hanwen/go-fuse/v2 v2.1.1-0.20221117175120-915cf5413cde - github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 - github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd // indirect - github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff // indirect - github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 // indirect - github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb // indirect github.com/pkg/xattr v0.4.3 github.com/rfjakob/eme v1.1.2 github.com/sabhiram/go-gitignore v0.0.0-20201211210132-54b8a0bf510f github.com/spf13/pflag v1.0.5 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 - golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect - golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 ) diff --git a/go.sum b/go.sum index 8da7877..ba3cf88 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,10 @@ +github.com/aperturerobotics/jacobsa-crypto v0.0.0-20190317225127-9f44e2d11115/go.mod h1:XKd7k7LIBmeR/WGENaSpUSjQbWBVKZFhMT7+zKM5KVU= +github.com/aperturerobotics/jacobsa-crypto v1.0.0 h1:ARfIuzgovK+5leAKbFHcicKEgMzD94tb/FTiWSHdGLU= +github.com/aperturerobotics/jacobsa-crypto v1.0.0/go.mod h1:xq0oOkHSPQ1E5ByqbwLhCJ1mygYHtXTMQnvHD4tz4Cc= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/hanwen/go-fuse/v2 v2.1.1-0.20211219085202-934a183ed914 h1:hGXMxS1wTE4y+f7iBqFArrJ6X8QozHnEdnVzGZI9Ywc= -github.com/hanwen/go-fuse/v2 v2.1.1-0.20211219085202-934a183ed914/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= -github.com/hanwen/go-fuse/v2 v2.1.1-0.20220822120740-58a7e145ff0d h1:nzUYOBVDJ6T1QjPbo7HMdmUlW7+DTV+E64AnNILQYhk= -github.com/hanwen/go-fuse/v2 v2.1.1-0.20220822120740-58a7e145ff0d/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= github.com/hanwen/go-fuse/v2 v2.1.1-0.20221117175120-915cf5413cde h1:fgTauqHA48CDt+qVQR+PJXqiI9bpYQglMIIi+h/mMts= github.com/hanwen/go-fuse/v2 v2.1.1-0.20221117175120-915cf5413cde/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= -github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 h1:YuDUUFNM21CAbyPOpOP8BicaTD/0klJEKt5p8yuw+uY= -github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115/go.mod h1:LadVJg0XuawGk+8L1rYnIED8451UyNxEMdTWCEt5kmU= github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd h1:9GCSedGjMcLZCrusBZuo4tyKLpKUPenUUqi34AkuFmA= github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd/go.mod h1:TlmyIZDpGmwRoTWiakdr+HA1Tukze6C6XbRVidYq02M= github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff h1:2xRHTvkpJ5zJmglXLRqHiZQNjUoOkhUyhTAhEQvPAWw= @@ -34,21 +31,21 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0= +golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= -golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/internal/siv_aead/correctness_test.go b/internal/siv_aead/correctness_test.go index b52774b..0653e26 100644 --- a/internal/siv_aead/correctness_test.go +++ b/internal/siv_aead/correctness_test.go @@ -5,7 +5,7 @@ import ( "encoding/hex" "testing" - "github.com/jacobsa/crypto/siv" + "github.com/aperturerobotics/jacobsa-crypto/siv" ) // Test all supported key lengths diff --git a/internal/siv_aead/siv_aead.go b/internal/siv_aead/siv_aead.go index 482efd9..dc37c8a 100644 --- a/internal/siv_aead/siv_aead.go +++ b/internal/siv_aead/siv_aead.go @@ -6,7 +6,7 @@ import ( "crypto/cipher" "log" - "github.com/jacobsa/crypto/siv" + "github.com/aperturerobotics/jacobsa-crypto/siv" ) type sivAead struct { @@ -63,7 +63,7 @@ func (s *sivAead) Seal(dst, nonce, plaintext, authData []byte) []byte { if len(s.key) == 0 { log.Panic("Key has been wiped?") } - // https://github.com/jacobsa/crypto/blob/master/siv/encrypt.go#L48: + // https://github.com/aperturerobotics/jacobsa-crypto/blob/master/siv/encrypt.go#L48: // As per RFC 5297 section 3, you may use this function for nonce-based // authenticated encryption by passing a nonce as the last associated // data element. diff --git a/internal/speed/speed.go b/internal/speed/speed.go index aef3ad6..950bbda 100644 --- a/internal/speed/speed.go +++ b/internal/speed/speed.go @@ -140,7 +140,7 @@ func bGoGCM(b *testing.B) { bEncrypt(b, gGCM) } -// bAESSIV benchmarks AES-SIV from github.com/jacobsa/crypto/siv +// bAESSIV benchmarks AES-SIV from github.com/aperturerobotics/jacobsa-crypto/siv func bAESSIV(b *testing.B) { c := siv_aead.New(randBytes(64)) bEncrypt(b, c) From ff32e9979130e6237b0d97ef88304fa79ce61b06 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 29 Dec 2022 13:52:35 +0100 Subject: [PATCH 06/20] main: doMount: call Setsid before starting logger The logger should be in the new background session together with the gocryptfs process. Before: $ xfce4-terminal -x gocryptfs a b $ ps xao pid,ppid,pgid,sid,comm,args PID PPID PGID SID COMMAND COMMAND 192272 1371 192272 192272 gocryptfs /ssd2/jakob.donotbackup/go/bin/gocryptfs -fg -notifypid=192265 a b 192292 192272 192265 192265 logge [logger] After: $ xfce4-terminal -x gocryptfs a b $ ps xao pid,ppid,pgid,sid,comm,args PID PPID PGID SID COMMAND COMMAND 211714 1371 211714 211714 gocryptfs /ssd2/jakob.donotbackup/go/bin/gocryptfs -fg -notifypid=211708 a b 211776 211714 211714 211714 logger logger -t gocryptfs-211714-logger Fixes https://github.com/rfjakob/gocryptfs/issues/660 --- mount.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/mount.go b/mount.go index 434edad..4d72778 100644 --- a/mount.go +++ b/mount.go @@ -120,9 +120,18 @@ func doMount(args *argContainer) { tlog.Info.Println(tlog.ColorGreen + "Filesystem mounted and ready." + tlog.ColorReset) // We have been forked into the background, as evidenced by the set // "notifypid". + // Do what daemons should do: https://man7.org/linux/man-pages/man7/daemon.7.html if args.notifypid > 0 { // Chdir to the root directory so we don't block unmounting the CWD os.Chdir("/") + // Disconnect from the controlling terminal by creating a new session. + // This prevents us from getting SIGINT when the user presses Ctrl-C + // to exit a running script that has called gocryptfs, or SIGHUP when + // xfce4-terminal closes itself ( https://github.com/rfjakob/gocryptfs/issues/660 ). + _, err = syscall.Setsid() + if err != nil { + tlog.Warn.Printf("Setsid: %v", err) + } // Switch to syslog if !args.nosyslog { // Switch all of our logs and the generic logger to syslog @@ -134,13 +143,6 @@ func doMount(args *argContainer) { // Daemons should redirect stdin, stdout and stderr redirectStdFds() } - // Disconnect from the controlling terminal by creating a new session. - // This prevents us from getting SIGINT when the user presses Ctrl-C - // to exit a running script that has called gocryptfs. - _, err = syscall.Setsid() - if err != nil { - tlog.Warn.Printf("Setsid: %v", err) - } // Send SIGUSR1 to our parent sendUsr1(args.notifypid) } From 439dea1b198a9edd384e3b9763a9c5672ce62b67 Mon Sep 17 00:00:00 2001 From: Daniel Theophanes Date: Wed, 28 Dec 2022 09:38:09 -0600 Subject: [PATCH 07/20] Use existing build information for version if not embedded with build script Go1.12 introduced BuildInfo which embeds build information. It does not embed build date to facilitate reproducable builds by default. If build information is embedded from build script, use the information provided by the Go build system. --- init_dir.go | 2 ++ main.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/init_dir.go b/init_dir.go index 5ade692..e895f00 100644 --- a/init_dir.go +++ b/init_dir.go @@ -55,6 +55,8 @@ func isDir(dir string) error { // In reverse mode, we create .gocryptfs.reverse.conf and the directory does // not need to be empty. func initDir(args *argContainer) { + initGIT() + var err error if args.reverse { _, err = os.Stat(args.config) diff --git a/main.go b/main.go index d1bf0c3..dad2c73 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "runtime" + "runtime/debug" "strconv" "strings" @@ -36,6 +37,51 @@ var BuildDate = "0000-00-00" // raceDetector is set to true by race.go if we are compiled with "go build -race" var raceDetector bool +func initGIT() { + bi, ok := debug.ReadBuildInfo() + if !ok { + return + } + if strings.HasPrefix(GitVersion, `[`) { + GitVersion = bi.Main.Version + var gitDate string + var gitDirty bool + for _, item := range bi.Settings { + switch item.Key { + case "vcs.revision": + GitVersion = item.Value + case "vcs.time": + gitDate = item.Value + gitDate = strings.Map(func(r rune) rune { + switch { + case r >= '0' && r <= '9': + return r + default: + return -1 + } + }, gitDate) + case "vcs.modified": + gitDirty, _ = strconv.ParseBool(item.Value) + } + } + if len(gitDate) > 0 { + GitVersion = gitDate + "-" + GitVersion + } + if gitDirty { + GitVersion = GitVersion + " (dirty)" + } + } + const fuseModule = `github.com/hanwen/go-fuse/v2` + + if strings.HasPrefix(GitVersionFuse, `[`) { + for _, item := range bi.Deps { + if item.Path == fuseModule { + GitVersionFuse = item.Version + } + } + } +} + // loadConfig loads the config file `args.config` and decrypts the masterkey, // or gets via the `-masterkey` or `-zerokey` command line options, if specified. func loadConfig(args *argContainer) (masterkey []byte, cf *configfile.ConfFile, err error) { @@ -140,6 +186,8 @@ func changePassword(args *argContainer) { // printVersion prints a version string like this: // gocryptfs v1.7-32-gcf99cfd; go-fuse v1.0.0-174-g22a9cb9; 2019-05-12 go1.12 linux/amd64 func printVersion() { + initGIT() + var tagsSlice []string if stupidgcm.BuiltWithoutOpenssl { tagsSlice = append(tagsSlice, "without_openssl") From 99cdaa0b69e884128e8f673f96bd4d3e32743d80 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 29 Dec 2022 14:43:09 +0100 Subject: [PATCH 08/20] main: refactor BuildInfo code Simplify and move it into a new file version.go. --- init_dir.go | 2 - main.go | 82 ----------------------------------------- version.go | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 84 deletions(-) create mode 100644 version.go diff --git a/init_dir.go b/init_dir.go index e895f00..5ade692 100644 --- a/init_dir.go +++ b/init_dir.go @@ -55,8 +55,6 @@ func isDir(dir string) error { // In reverse mode, we create .gocryptfs.reverse.conf and the directory does // not need to be empty. func initDir(args *argContainer) { - initGIT() - var err error if args.reverse { _, err = os.Stat(args.config) diff --git a/main.go b/main.go index dad2c73..7facf78 100644 --- a/main.go +++ b/main.go @@ -4,12 +4,10 @@ package main import ( - "fmt" "log" "os" "path/filepath" "runtime" - "runtime/debug" "strconv" "strings" @@ -21,67 +19,9 @@ import ( "github.com/rfjakob/gocryptfs/v2/internal/fido2" "github.com/rfjakob/gocryptfs/v2/internal/readpassword" "github.com/rfjakob/gocryptfs/v2/internal/speed" - "github.com/rfjakob/gocryptfs/v2/internal/stupidgcm" "github.com/rfjakob/gocryptfs/v2/internal/tlog" ) -// GitVersion is the gocryptfs version according to git, set by build.bash -var GitVersion = "[GitVersion not set - please compile using ./build.bash]" - -// GitVersionFuse is the go-fuse library version, set by build.bash -var GitVersionFuse = "[GitVersionFuse not set - please compile using ./build.bash]" - -// BuildDate is a date string like "2017-09-06", set by build.bash -var BuildDate = "0000-00-00" - -// raceDetector is set to true by race.go if we are compiled with "go build -race" -var raceDetector bool - -func initGIT() { - bi, ok := debug.ReadBuildInfo() - if !ok { - return - } - if strings.HasPrefix(GitVersion, `[`) { - GitVersion = bi.Main.Version - var gitDate string - var gitDirty bool - for _, item := range bi.Settings { - switch item.Key { - case "vcs.revision": - GitVersion = item.Value - case "vcs.time": - gitDate = item.Value - gitDate = strings.Map(func(r rune) rune { - switch { - case r >= '0' && r <= '9': - return r - default: - return -1 - } - }, gitDate) - case "vcs.modified": - gitDirty, _ = strconv.ParseBool(item.Value) - } - } - if len(gitDate) > 0 { - GitVersion = gitDate + "-" + GitVersion - } - if gitDirty { - GitVersion = GitVersion + " (dirty)" - } - } - const fuseModule = `github.com/hanwen/go-fuse/v2` - - if strings.HasPrefix(GitVersionFuse, `[`) { - for _, item := range bi.Deps { - if item.Path == fuseModule { - GitVersionFuse = item.Version - } - } - } -} - // loadConfig loads the config file `args.config` and decrypts the masterkey, // or gets via the `-masterkey` or `-zerokey` command line options, if specified. func loadConfig(args *argContainer) (masterkey []byte, cf *configfile.ConfFile, err error) { @@ -183,28 +123,6 @@ func changePassword(args *argContainer) { tlog.Info.Printf(tlog.ColorGreen + "Password changed." + tlog.ColorReset) } -// printVersion prints a version string like this: -// gocryptfs v1.7-32-gcf99cfd; go-fuse v1.0.0-174-g22a9cb9; 2019-05-12 go1.12 linux/amd64 -func printVersion() { - initGIT() - - var tagsSlice []string - if stupidgcm.BuiltWithoutOpenssl { - tagsSlice = append(tagsSlice, "without_openssl") - } - tags := "" - if tagsSlice != nil { - tags = " " + strings.Join(tagsSlice, " ") - } - built := fmt.Sprintf("%s %s", BuildDate, runtime.Version()) - if raceDetector { - built += " -race" - } - fmt.Printf("%s %s%s; go-fuse %s; %s %s/%s\n", - tlog.ProgramName, GitVersion, tags, GitVersionFuse, built, - runtime.GOOS, runtime.GOARCH) -} - func main() { mxp := runtime.GOMAXPROCS(0) if mxp < 4 && os.Getenv("GOMAXPROCS") == "" { diff --git a/version.go b/version.go new file mode 100644 index 0000000..97bf83a --- /dev/null +++ b/version.go @@ -0,0 +1,103 @@ +package main + +import ( + "fmt" + "runtime" + "runtime/debug" + "strconv" + "strings" + + "github.com/rfjakob/gocryptfs/v2/internal/stupidgcm" + "github.com/rfjakob/gocryptfs/v2/internal/tlog" +) + +const ( + gitVersionNotSet = "[GitVersion not set - please compile using ./build.bash]" + gitVersionFuseNotSet = "[GitVersionFuse not set - please compile using ./build.bash]" + buildDateNotSet = "0000-00-00" +) + +var ( + // GitVersion is the gocryptfs version according to git, set by build.bash + GitVersion = gitVersionNotSet + // GitVersionFuse is the go-fuse library version, set by build.bash + GitVersionFuse = gitVersionFuseNotSet + // BuildDate is a date string like "2017-09-06", set by build.bash + BuildDate = buildDateNotSet +) + +func init() { + versionFromBuildInfo() +} + +// raceDetector is set to true by race.go if we are compiled with "go build -race" +var raceDetector bool + +// printVersion prints a version string like this: +// gocryptfs v1.7-32-gcf99cfd; go-fuse v1.0.0-174-g22a9cb9; 2019-05-12 go1.12 linux/amd64 +func printVersion() { + var tagsSlice []string + if stupidgcm.BuiltWithoutOpenssl { + tagsSlice = append(tagsSlice, "without_openssl") + } + tags := "" + if tagsSlice != nil { + tags = " " + strings.Join(tagsSlice, " ") + } + built := fmt.Sprintf("%s %s", BuildDate, runtime.Version()) + if raceDetector { + built += " -race" + } + fmt.Printf("%s %s%s; go-fuse %s; %s %s/%s\n", + tlog.ProgramName, GitVersion, tags, GitVersionFuse, built, + runtime.GOOS, runtime.GOARCH) +} + +// versionFromBuildInfo tries to get some information out of the information baked in +// by the Go compiler. Does nothing when build.bash was used to build. +func versionFromBuildInfo() { + info, ok := debug.ReadBuildInfo() + if !ok { + tlog.Debug.Println("versionFromBuildInfo: ReadBuildInfo() failed") + return + } + // Parse BuildSettings + var vcsRevision, vcsTime string + var vcsModified bool + for _, s := range info.Settings { + switch s.Key { + case "vcs.revision": + vcsRevision = s.Value + case "vcs.time": + vcsTime = s.Value + case "vcs.modified": + vcsModified, _ = strconv.ParseBool(s.Value) + } + } + // Fill our version strings + if GitVersion == gitVersionNotSet { + GitVersion = info.Main.Version + if GitVersion == "(devel)" && vcsRevision != "" { + GitVersion = fmt.Sprintf("vcs.revision=%s", vcsRevision) + } + if vcsModified { + GitVersion += "-dirty" + } + } + if GitVersionFuse == gitVersionFuseNotSet { + for _, m := range info.Deps { + if m.Path == "github.com/hanwen/go-fuse/v2" { + GitVersionFuse = m.Version + if m.Replace != nil { + GitVersionFuse = m.Replace.Version + } + break + } + } + } + if BuildDate == buildDateNotSet { + if vcsTime != "" { + BuildDate = fmt.Sprintf("vcs.time=%s", vcsTime) + } + } +} From 856ccaac10579abda5620dfc86ad6031b1076a43 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 29 Dec 2022 15:00:24 +0100 Subject: [PATCH 09/20] make format Run "make format" using go version go1.19.4 linux/amd64 --- internal/ctlsocksrv/sanitize.go | 9 ++--- internal/ensurefds012/ensurefds012.go | 18 +++++----- .../fusefrontend/file_allocate_truncate.go | 4 +-- internal/inomap/inomap.go | 4 +-- internal/speed/cpuinfo.go | 12 +++---- internal/stupidgcm/doc.go | 36 +++++++++---------- internal/stupidgcm/prefer.go | 6 ++-- tests/cli/cli_test.go | 4 ++- tests/defaults/main_test.go | 4 ++- tests/matrix/concurrency_test.go | 2 +- tests/plaintextnames/plaintextnames_test.go | 8 ++--- tests/reverse/inomap_test.go | 12 +++---- tests/test_helpers/helpers.go | 10 +++--- 13 files changed, 67 insertions(+), 62 deletions(-) diff --git a/internal/ctlsocksrv/sanitize.go b/internal/ctlsocksrv/sanitize.go index 4333872..2272943 100644 --- a/internal/ctlsocksrv/sanitize.go +++ b/internal/ctlsocksrv/sanitize.go @@ -6,10 +6,11 @@ import ( ) // SanitizePath adapts filepath.Clean for FUSE paths. -// 1) Leading slash(es) are dropped -// 2) It returns "" instead of "." -// 3) If the cleaned path points above CWD (start with ".."), an empty string -// is returned +// 1. Leading slash(es) are dropped +// 2. It returns "" instead of "." +// 3. If the cleaned path points above CWD (start with ".."), an empty string +// is returned +// // See the TestSanitizePath testcases for examples. func SanitizePath(path string) string { // (1) diff --git a/internal/ensurefds012/ensurefds012.go b/internal/ensurefds012/ensurefds012.go index 54a1ac1..6834b89 100644 --- a/internal/ensurefds012/ensurefds012.go +++ b/internal/ensurefds012/ensurefds012.go @@ -5,7 +5,7 @@ // // Use like this: // -// import _ "github.com/rfjakob/gocryptfs/v2/internal/ensurefds012" +// import _ "github.com/rfjakob/gocryptfs/v2/internal/ensurefds012" // // The import line MUST be in the alphabitcally first source code file of // package main! @@ -13,17 +13,17 @@ // You can test if it works as expected by inserting a long sleep into main, // startings gocryptfs with all fds closed like this, // -// $ ./gocryptfs 0<&- 1>&- 2>&- +// $ ./gocryptfs 0<&- 1>&- 2>&- // // and then checking the open fds. It should look like this: // -// $ ls -l /proc/$(pgrep gocryptfs)/fd -// total 0 -// lrwx------. 1 jakob jakob 64 Jan 5 15:54 0 -> /dev/null -// lrwx------. 1 jakob jakob 64 Jan 5 15:54 1 -> /dev/null -// lrwx------. 1 jakob jakob 64 Jan 5 15:54 2 -> /dev/null -// l-wx------. 1 jakob jakob 64 Jan 5 15:54 3 -> /dev/null -// lrwx------. 1 jakob jakob 64 Jan 5 15:54 4 -> 'anon_inode:[eventpoll]' +// $ ls -l /proc/$(pgrep gocryptfs)/fd +// total 0 +// lrwx------. 1 jakob jakob 64 Jan 5 15:54 0 -> /dev/null +// lrwx------. 1 jakob jakob 64 Jan 5 15:54 1 -> /dev/null +// lrwx------. 1 jakob jakob 64 Jan 5 15:54 2 -> /dev/null +// l-wx------. 1 jakob jakob 64 Jan 5 15:54 3 -> /dev/null +// lrwx------. 1 jakob jakob 64 Jan 5 15:54 4 -> 'anon_inode:[eventpoll]' // // See https://github.com/rfjakob/gocryptfs/issues/320 for details. package ensurefds012 diff --git a/internal/fusefrontend/file_allocate_truncate.go b/internal/fusefrontend/file_allocate_truncate.go index fddcfe8..cae796e 100644 --- a/internal/fusefrontend/file_allocate_truncate.go +++ b/internal/fusefrontend/file_allocate_truncate.go @@ -30,8 +30,8 @@ var allocateWarnOnce sync.Once // // mode=FALLOC_DEFAULT is implemented as a two-step process: // -// (1) Allocate the space using FALLOC_FL_KEEP_SIZE -// (2) Set the file size using ftruncate (via truncateGrowFile) +// (1) Allocate the space using FALLOC_FL_KEEP_SIZE +// (2) Set the file size using ftruncate (via truncateGrowFile) // // This allows us to reuse the file grow mechanics from Truncate as they are // complicated and hard to get right. diff --git a/internal/inomap/inomap.go b/internal/inomap/inomap.go index 070fab4..0f7ade3 100644 --- a/internal/inomap/inomap.go +++ b/internal/inomap/inomap.go @@ -3,8 +3,8 @@ // // Format of the returned inode numbers: // -// [spill bit = 0][15 bit namespace id][48 bit passthru inode number] -// [spill bit = 1][63 bit spill inode number ] +// [spill bit = 0][15 bit namespace id][48 bit passthru inode number] +// [spill bit = 1][63 bit spill inode number ] // // Each (Dev, Tag) tuple gets a namespace id assigned. The original inode // number is then passed through in the lower 48 bits. diff --git a/internal/speed/cpuinfo.go b/internal/speed/cpuinfo.go index 09e7a89..df3177d 100644 --- a/internal/speed/cpuinfo.go +++ b/internal/speed/cpuinfo.go @@ -12,17 +12,17 @@ import ( // // Examples: On my desktop PC: // -// $ grep "model name" /proc/cpuinfo -// model name : Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz +// $ grep "model name" /proc/cpuinfo +// model name : Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz // // --> Returns "Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz". // // On a Raspberry Pi 4: // -// $ grep "model name" /proc/cpuinfo -// (empty) -// $ grep Hardware /proc/cpuinfo -// Hardware : BCM2835 +// $ grep "model name" /proc/cpuinfo +// (empty) +// $ grep Hardware /proc/cpuinfo +// Hardware : BCM2835 // // --> Returns "BCM2835" func cpuModelName() string { diff --git a/internal/stupidgcm/doc.go b/internal/stupidgcm/doc.go index 36c189b..dce82ae 100644 --- a/internal/stupidgcm/doc.go +++ b/internal/stupidgcm/doc.go @@ -16,13 +16,13 @@ // However, OpenSSL has optimized assembly for almost all platforms, which Go // does not. Example for a 32-bit ARM device (Odroid XU4): // -// $ gocrypts -speed -// gocryptfs v2.1-68-gedf9d4c.stupidchacha; go-fuse v2.1.1-0.20210825171523-3ab5d95a30ae; 2021-09-04 go1.16.7 linux/arm -// AES-GCM-256-OpenSSL 56.84 MB/s (selected in auto mode) -// AES-GCM-256-Go 16.61 MB/s -// AES-SIV-512-Go 16.49 MB/s -// XChaCha20-Poly1305-Go 39.08 MB/s (use via -xchacha flag) -// XChaCha20-Poly1305-OpenSSL 141.82 MB/s +// $ gocrypts -speed +// gocryptfs v2.1-68-gedf9d4c.stupidchacha; go-fuse v2.1.1-0.20210825171523-3ab5d95a30ae; 2021-09-04 go1.16.7 linux/arm +// AES-GCM-256-OpenSSL 56.84 MB/s (selected in auto mode) +// AES-GCM-256-Go 16.61 MB/s +// AES-SIV-512-Go 16.49 MB/s +// XChaCha20-Poly1305-Go 39.08 MB/s (use via -xchacha flag) +// XChaCha20-Poly1305-OpenSSL 141.82 MB/s // // This package is "stupid" in the sense that it only supports a narrow set of // key- and iv-lengths, and panics if it does not like what you pass it. @@ -33,7 +33,7 @@ // Corrupt ciphertexts never cause a panic. Instead, ErrAuth is returned on // decryption. // -// XChaCha20-Poly1305 +// # XChaCha20-Poly1305 // // The XChaCha20-Poly1305 implementation is more complicated than the others, // because OpenSSL does not support XChaCha20-Poly1305 directly. Follow @@ -43,16 +43,16 @@ // Fortunately, XChaCha20-Poly1305 is just ChaCha20-Poly1305 with some key+iv // mixing using HChaCha20 in front: // -// key (32 bytes), iv (24 bytes) -// | -// v -// HChaCha20 (provided by golang.org/x/crypto/chacha20) -// | -// v -// key2 (32 bytes), iv2 (16 bytes) -// | -// v -// ChaCha20-Poly1305 (OpenSSL EVP_chacha20_poly1305) +// key (32 bytes), iv (24 bytes) +// | +// v +// HChaCha20 (provided by golang.org/x/crypto/chacha20) +// | +// v +// key2 (32 bytes), iv2 (16 bytes) +// | +// v +// ChaCha20-Poly1305 (OpenSSL EVP_chacha20_poly1305) // // As HChaCha20 is very fast, XChaCha20-Poly1305 gets almost the same throughput // as ChaCha20-Poly1305 (for 4kiB blocks). diff --git a/internal/stupidgcm/prefer.go b/internal/stupidgcm/prefer.go index fe8c613..e3f52d4 100644 --- a/internal/stupidgcm/prefer.go +++ b/internal/stupidgcm/prefer.go @@ -11,9 +11,9 @@ import ( // // Go GCM is only faster if the CPU either: // -// 1) Is X86_64 && has AES instructions && Go is v1.6 or higher -// 2) Is ARM64 && has AES instructions && Go is v1.11 or higher -// (commit https://github.com/golang/go/commit/4f1f503373cda7160392be94e3849b0c9b9ebbda) +// 1. Is X86_64 && has AES instructions && Go is v1.6 or higher +// 2. Is ARM64 && has AES instructions && Go is v1.11 or higher +// (commit https://github.com/golang/go/commit/4f1f503373cda7160392be94e3849b0c9b9ebbda) // // See https://github.com/rfjakob/gocryptfs/wiki/CPU-Benchmarks // for benchmarks. diff --git a/tests/cli/cli_test.go b/tests/cli/cli_test.go index fc2bfed..bbaca51 100644 --- a/tests/cli/cli_test.go +++ b/tests/cli/cli_test.go @@ -462,7 +462,9 @@ func TestPasswdPasswordIncorrect(t *testing.T) { // Check that we correctly background on mount and close stderr and stdout. // Something like -// gocryptfs a b | cat +// +// gocryptfs a b | cat +// // must not hang ( https://github.com/rfjakob/gocryptfs/issues/130 ). func TestMountBackground(t *testing.T) { dir := test_helpers.InitFS(t) diff --git a/tests/defaults/main_test.go b/tests/defaults/main_test.go index 7633e8b..d0210e2 100644 --- a/tests/defaults/main_test.go +++ b/tests/defaults/main_test.go @@ -204,7 +204,9 @@ func TestWrite0200File(t *testing.T) { // TestMvWarnings: // When xattr support was introduced, mv threw warnings like these: -// mv: preserving permissions for ‘b/x’: Operation not permitted +// +// mv: preserving permissions for ‘b/x’: Operation not permitted +// // because we returned EPERM when it tried to set system.posix_acl_access. // Now we return EOPNOTSUPP and mv is happy. func TestMvWarnings(t *testing.T) { diff --git a/tests/matrix/concurrency_test.go b/tests/matrix/concurrency_test.go index 4f060ab..15dbc3e 100644 --- a/tests/matrix/concurrency_test.go +++ b/tests/matrix/concurrency_test.go @@ -134,7 +134,7 @@ func TestConcurrentReadCreate(t *testing.T) { // // So far, it only has triggered warnings like this // -// go-fuse: warning: Inode.Path: inode i4201033 is orphaned, replacing segment with ".go-fuse.5577006791947779410/deleted" +// go-fuse: warning: Inode.Path: inode i4201033 is orphaned, replacing segment with ".go-fuse.5577006791947779410/deleted" // // but none of the "blocked waiting for FORGET". func TestInoReuse(t *testing.T) { diff --git a/tests/plaintextnames/plaintextnames_test.go b/tests/plaintextnames/plaintextnames_test.go index f2dc7e7..8892c39 100644 --- a/tests/plaintextnames/plaintextnames_test.go +++ b/tests/plaintextnames/plaintextnames_test.go @@ -92,10 +92,10 @@ func TestFiltered(t *testing.T) { // Only works on filesystems that recycle inode numbers (ext4 does), // and then the test causes a hang with these messages: // -// go-fuse: blocked for 5 seconds waiting for FORGET on i4329366 -// go-fuse: blocked for 11 seconds waiting for FORGET on i4329366 -// go-fuse: blocked for 17 seconds waiting for FORGET on i4329366 -// [...] +// go-fuse: blocked for 5 seconds waiting for FORGET on i4329366 +// go-fuse: blocked for 11 seconds waiting for FORGET on i4329366 +// go-fuse: blocked for 17 seconds waiting for FORGET on i4329366 +// [...] // // The test runs with -plaintextnames because that makes it easier to manipulate // cipherdir directly. diff --git a/tests/reverse/inomap_test.go b/tests/reverse/inomap_test.go index d5544c8..a79ddd2 100644 --- a/tests/reverse/inomap_test.go +++ b/tests/reverse/inomap_test.go @@ -35,15 +35,15 @@ func findIno(dir string, ino uint64) string { // TestVirtualFileIno creates a directory tree like this: // -// TestVirtualFileIno <---- parent -// └── xxxxxxx[...] <---- child +// TestVirtualFileIno <---- parent +// └── xxxxxxx[...] <---- child // // Which looks like this encrypted: // -// OLUKdPMg6l87EiKVlufgwIkQL8MD6JdUgOR3a8nEZ-w <---- parent -// ├── gocryptfs.diriv <---- diriv -// ├── gocryptfs.longname.e31v1ax4h_F0l4jhlN8kCjaWWMq8rO9VVBZ15IYsV50 <---- child -// └── gocryptfs.longname.e31v1ax4h_F0l4jhlN8kCjaWWMq8rO9VVBZ15IYsV50.name <---- name +// OLUKdPMg6l87EiKVlufgwIkQL8MD6JdUgOR3a8nEZ-w <---- parent +// ├── gocryptfs.diriv <---- diriv +// ├── gocryptfs.longname.e31v1ax4h_F0l4jhlN8kCjaWWMq8rO9VVBZ15IYsV50 <---- child +// └── gocryptfs.longname.e31v1ax4h_F0l4jhlN8kCjaWWMq8rO9VVBZ15IYsV50.name <---- name // // It verifies that the inode numbers match what we expect. func TestVirtualFileIno(t *testing.T) { diff --git a/tests/test_helpers/helpers.go b/tests/test_helpers/helpers.go index daa37d7..0d21548 100644 --- a/tests/test_helpers/helpers.go +++ b/tests/test_helpers/helpers.go @@ -67,10 +67,10 @@ func doInit() { // ResetTmpDir deletes TmpDir, create new dir tree: // -// TmpDir -// |-- DefaultPlainDir -// *-- DefaultCipherDir -// *-- gocryptfs.diriv +// TmpDir +// |-- DefaultPlainDir +// *-- DefaultCipherDir +// *-- gocryptfs.diriv func ResetTmpDir(createDirIV bool) { // Try to unmount and delete everything entries, err := ioutil.ReadDir(TmpDir) @@ -138,7 +138,7 @@ func isExt4(path string) bool { // InitFS creates a new empty cipherdir and calls // -// gocryptfs -q -init -extpass "echo test" -scryptn=10 $extraArgs $cipherdir +// gocryptfs -q -init -extpass "echo test" -scryptn=10 $extraArgs $cipherdir // // It returns cipherdir without a trailing slash. // From b2a5cec4dddd0bc4ece65ece2dd32908c5c2c994 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 29 Dec 2022 15:21:17 +0100 Subject: [PATCH 10/20] main: BuildInfo: fix build with Go 1.17 and older On Go 1.17 and older we get this: Error: ./version.go:67:24: info.Settings undefined (type *debug.BuildInfo has no field or method Settings) Fix the build error by shedding some nice-to-have features. --- version.go | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/version.go b/version.go index 97bf83a..22c780b 100644 --- a/version.go +++ b/version.go @@ -4,7 +4,6 @@ import ( "fmt" "runtime" "runtime/debug" - "strconv" "strings" "github.com/rfjakob/gocryptfs/v2/internal/stupidgcm" @@ -61,28 +60,9 @@ func versionFromBuildInfo() { tlog.Debug.Println("versionFromBuildInfo: ReadBuildInfo() failed") return } - // Parse BuildSettings - var vcsRevision, vcsTime string - var vcsModified bool - for _, s := range info.Settings { - switch s.Key { - case "vcs.revision": - vcsRevision = s.Value - case "vcs.time": - vcsTime = s.Value - case "vcs.modified": - vcsModified, _ = strconv.ParseBool(s.Value) - } - } // Fill our version strings - if GitVersion == gitVersionNotSet { + if GitVersion == gitVersionNotSet && info.Main.Version != "(devel)" { GitVersion = info.Main.Version - if GitVersion == "(devel)" && vcsRevision != "" { - GitVersion = fmt.Sprintf("vcs.revision=%s", vcsRevision) - } - if vcsModified { - GitVersion += "-dirty" - } } if GitVersionFuse == gitVersionFuseNotSet { for _, m := range info.Deps { @@ -95,9 +75,4 @@ func versionFromBuildInfo() { } } } - if BuildDate == buildDateNotSet { - if vcsTime != "" { - BuildDate = fmt.Sprintf("vcs.time=%s", vcsTime) - } - } } From c4b95cf35ab7468dfeab5bfa2e96420a640c9337 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 29 Dec 2022 15:28:59 +0100 Subject: [PATCH 11/20] github ci: bump actions ; add "stable" and "oldstable" Go versions --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b410bed..b9d868a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,16 +13,16 @@ jobs: go: - "1.13.x" # Ubuntu 20.04 LTS "focal" - "1.15.x" # Debian 11 "Bullseye" - - "1.17.x" # Golang upstream stable - - "1.18.x" # Golang upstream stable - - "1.19.x" # Golang upstream stable + - "1.18.x" # Ubuntu 22.04 LTS "jammy" + - "oldstable" # 2nd-latest Golang upstream stable + - "stable" # Latest Go upstream stable # Don't cancel everything when one Go version fails fail-fast: false runs-on: ubuntu-latest steps: - name: Install Go ${{ matrix.go }} - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ${{ matrix.go }} @@ -30,7 +30,7 @@ jobs: # https://github.com/actions/runner/issues/1188 - run: ls -l /proc/self/fd - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # Make "git describe" work @@ -42,7 +42,7 @@ jobs: # Build & upload static binary - run: ./build-without-openssl.bash - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: gocryptfs static binary (Go ${{ matrix.go }}) path: gocryptfs From 3c1ac3b06b5dea652aa94bf85b7276f17422b210 Mon Sep 17 00:00:00 2001 From: a1346054 <36859588+a1346054@users.noreply.github.com> Date: Fri, 30 Dec 2022 20:02:17 +0000 Subject: [PATCH 12/20] MANPAGE.md: use correct indefinite article a->an --- Documentation/MANPAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md index 998c8e0..8f96745 100644 --- a/Documentation/MANPAGE.md +++ b/Documentation/MANPAGE.md @@ -482,7 +482,7 @@ Use "fido2-token -L" to obtain the FIDO2 token device path. Applies to: all actions that ask for a password. #### -masterkey string -Use a explicit master key specified on the command line or, if the special +Use an explicit master key specified on the command line or, if the special value "stdin" is used, read the masterkey from stdin, instead of reading the config file and asking for the decryption password. From 0b5b864a067a530ed00f01baf12ad4de5bb60e27 Mon Sep 17 00:00:00 2001 From: Gisi0 Date: Fri, 6 Jan 2023 19:57:39 +0100 Subject: [PATCH 13/20] Update MANPAGE.md added which package on linux is needed to use fido2 stick --- Documentation/MANPAGE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md index 8f96745..45c60c6 100644 --- a/Documentation/MANPAGE.md +++ b/Documentation/MANPAGE.md @@ -478,6 +478,7 @@ for details. #### -fido2 DEVICE_PATH Use a FIDO2 token to initialize and unlock the filesystem. Use "fido2-token -L" to obtain the FIDO2 token device path. +For linux, "fido2-tools" package is needed. Applies to: all actions that ask for a password. From 88bc0aa60748405db94410c8f149e62683638f80 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 8 Jan 2023 22:15:39 +0100 Subject: [PATCH 14/20] MANPAGE: scryptn: list how much memory is needed Calculated acc. to https://words.filippo.io/the-scrypt-parameters/ , and add benchmarks to double-check the numbers. They match. --- Documentation/MANPAGE.md | 33 ++++++++++++- internal/configfile/scrypt_test.go | 75 ++++++++++++------------------ 2 files changed, 61 insertions(+), 47 deletions(-) diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md index 45c60c6..47092cf 100644 --- a/Documentation/MANPAGE.md +++ b/Documentation/MANPAGE.md @@ -563,15 +563,44 @@ Quiet - silence informational messages. Applies to: all actions. #### -scryptn int -scrypt cost parameter expressed as scryptn=log2(N). Possible values are -10 to 28, representing N=2^10 to N=2^28. +gocryptfs uses *scrypt* for hashing the password when mounting, +which protects from brute-force attacks. + +`-scryptn` controls the *scrypt* cost parameter "N" expressed as scryptn=log2(N). +Possible values are `-scryptn=10` to `-scryptn=28`, representing N=2^10 to N=2^28. Setting this to a lower value speeds up mounting and reduces its memory needs, but makes the password susceptible to brute-force attacks. The default is 16. +The memory usage for *scrypt* during mounting is as follows: + + scryptn Memory Usage + ======= ============ + 10 1 MiB + 11 2 + 12 4 + 13 8 + 14 16 + 15 32 + 16 64 + 17 128 + 18 256 + 19 512 + 20 1 GiB + 21 2 + 22 4 + 23 8 + 24 16 + 25 32 + 26 64 + 27 128 + 28 256 + Applies to: `-init`, `-passwd` +See also: the benchmarks in the gocryptfs source code in internal/configfile. + #### -trace string Write execution trace to file. View the trace using "go tool trace FILE". diff --git a/internal/configfile/scrypt_test.go b/internal/configfile/scrypt_test.go index 30f37a1..1c90c0a 100644 --- a/internal/configfile/scrypt_test.go +++ b/internal/configfile/scrypt_test.go @@ -1,60 +1,45 @@ package configfile import ( + "fmt" "testing" ) /* -Results on a 2.7GHz Pentium G630: - -gocryptfs/cryptfs$ go test -bench=. +$ time go test -bench . -run none +goos: linux +goarch: amd64 +pkg: github.com/rfjakob/gocryptfs/v2/internal/configfile +cpu: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz +BenchmarkScryptN/10-4 339 3488649 ns/op 1053167 B/op 22 allocs/op ... 3ms+1MiB +BenchmarkScryptN/11-4 175 6816072 ns/op 2101742 B/op 22 allocs/op +BenchmarkScryptN/12-4 87 13659346 ns/op 4198898 B/op 22 allocs/op +BenchmarkScryptN/13-4 43 27443071 ns/op 8393209 B/op 22 allocs/op +BenchmarkScryptN/14-4 21 56931664 ns/op 16781820 B/op 22 allocs/op +BenchmarkScryptN/15-4 10 108494502 ns/op 33559027 B/op 22 allocs/op +BenchmarkScryptN/16-4 5 217347137 ns/op 67113465 B/op 22 allocs/op ... 217ms+67MiB +BenchmarkScryptN/17-4 3 449680138 ns/op 134222362 B/op 22 allocs/op +BenchmarkScryptN/18-4 2 867481653 ns/op 268440064 B/op 22 allocs/op +BenchmarkScryptN/19-4 1 1738085333 ns/op 536875536 B/op 23 allocs/op +BenchmarkScryptN/20-4 1 3508224867 ns/op 1073746448 B/op 23 allocs/op +BenchmarkScryptN/21-4 1 9536561994 ns/op 2147488272 B/op 23 allocs/op +BenchmarkScryptN/22-4 1 16937072495 ns/op 4294971920 B/op 23 allocs/op PASS -BenchmarkScrypt10-2 300 6021435 ns/op ... 6ms -BenchmarkScrypt11-2 100 11861460 ns/op -BenchmarkScrypt12-2 100 23420822 ns/op -BenchmarkScrypt13-2 30 47666518 ns/op -BenchmarkScrypt14-2 20 92561590 ns/op ... 92ms -BenchmarkScrypt15-2 10 183971593 ns/op -BenchmarkScrypt16-2 3 368506365 ns/op -BenchmarkScrypt17-2 2 755502608 ns/op ... 755ms -ok github.com/rfjakob/gocryptfs/v2/cryptfs 18.772s +ok github.com/rfjakob/gocryptfs/v2/internal/configfile 47.545s */ -func benchmarkScryptN(n int, b *testing.B) { +func BenchmarkScryptN(b *testing.B) { + for n := 10; n <= 20; n++ { + b.Run(fmt.Sprintf("%d", n), func(b *testing.B) { + benchmarkScryptN(b, n) + }) + } +} + +func benchmarkScryptN(b *testing.B, n int) { kdf := NewScryptKDF(n) for i := 0; i < b.N; i++ { kdf.DeriveKey(testPw) } -} - -func BenchmarkScrypt10(b *testing.B) { - benchmarkScryptN(10, b) -} - -func BenchmarkScrypt11(b *testing.B) { - benchmarkScryptN(11, b) -} - -func BenchmarkScrypt12(b *testing.B) { - benchmarkScryptN(12, b) -} - -func BenchmarkScrypt13(b *testing.B) { - benchmarkScryptN(13, b) -} - -func BenchmarkScrypt14(b *testing.B) { - benchmarkScryptN(14, b) -} - -func BenchmarkScrypt15(b *testing.B) { - benchmarkScryptN(15, b) -} - -func BenchmarkScrypt16(b *testing.B) { - benchmarkScryptN(16, b) -} - -func BenchmarkScrypt17(b *testing.B) { - benchmarkScryptN(17, b) + b.ReportAllocs() } From 6dc8c2610077e4f8f7f85b5d3a22df454883285c Mon Sep 17 00:00:00 2001 From: Evgeny Date: Mon, 30 Jan 2023 17:13:24 +0700 Subject: [PATCH 15/20] MANPAGE: add a note on enabling Trash on macOS --- Documentation/MANPAGE.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md index 47092cf..4e9ab78 100644 --- a/Documentation/MANPAGE.md +++ b/Documentation/MANPAGE.md @@ -305,8 +305,10 @@ runs as root, you can enable device files by passing the opposite mount option, "dev", and if you want to enable suid-binaries, pass "suid". "ro" (equivalent to passing the "-ro" option) and "noexec" may also be interesting. For a complete list see the section -`FILESYSTEM-INDEPENDENT MOUNT OPTIONS` in mount(8). On MacOS, "local", -"noapplexattr", "noappledouble" may be interesting. +`FILESYSTEM-INDEPENDENT MOUNT OPTIONS` in mount(8). On MacOS, "local" enables volume-based trash +if you have `.Trashes` folder in the root of your volume (might need to be manually created) +note, though, that "local" is marked as "experimental" in [osxfuse](https://github.com/osxfuse/osxfuse/wiki/Mount-options#local); +"noapplexattr", "noappledouble" may also be interesting. Note that unlike "-o", "-ko" is a regular option and must be passed BEFORE the directories. Example: From e9a5b8962b0fc128acb95b75c2aabc0894d3e4ba Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Tue, 24 Jan 2023 21:35:32 +0100 Subject: [PATCH 16/20] contentenc: simplify testRange tables Get rid of this eyesore. --- internal/contentenc/content_test.go | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/contentenc/content_test.go b/internal/contentenc/content_test.go index 4a4b2de..b20ccb1 100644 --- a/internal/contentenc/content_test.go +++ b/internal/contentenc/content_test.go @@ -12,15 +12,15 @@ type testRange struct { } func TestSplitRange(t *testing.T) { - var ranges []testRange - - ranges = append(ranges, testRange{0, 70000}, - testRange{0, 10}, - testRange{234, 6511}, - testRange{65444, 54}, - testRange{0, 1024 * 1024}, - testRange{0, 65536}, - testRange{6654, 8945}) + ranges := []testRange{ + {0, 70000}, + {0, 10}, + {234, 6511}, + {65444, 54}, + {0, 1024 * 1024}, + {0, 65536}, + {6654, 8945}, + } key := make([]byte, cryptocore.KeyLen) cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true) @@ -42,13 +42,13 @@ func TestSplitRange(t *testing.T) { } func TestCiphertextRange(t *testing.T) { - var ranges []testRange - - ranges = append(ranges, testRange{0, 70000}, - testRange{0, 10}, - testRange{234, 6511}, - testRange{65444, 54}, - testRange{6654, 8945}) + ranges := []testRange{ + {0, 70000}, + {0, 10}, + {234, 6511}, + {65444, 54}, + {6654, 8945}, + } key := make([]byte, cryptocore.KeyLen) cc := cryptocore.New(key, cryptocore.BackendGoGCM, DefaultIVBits, true) From 85297cda97d018b514361a2088a78f50f1446f95 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Tue, 24 Jan 2023 22:07:28 +0100 Subject: [PATCH 17/20] fusefrontend: doWrite: report readFileID errors as I/O error It used to be reported as "function not implemented", accompanied with this log output: go-fuse: can't convert error type: ParseHeader: header is all-zero. Header hexdump: 000000000000000000000000000000000000 Now we report EIO and log this: doWrite 1372183: corrupt header: ParseHeader: header is all-zero. Header hexdump: 000000000000000000000000000000000000 --- internal/fusefrontend/file.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/fusefrontend/file.go b/internal/fusefrontend/file.go index 2f111fd..ff26a6e 100644 --- a/internal/fusefrontend/file.go +++ b/internal/fusefrontend/file.go @@ -273,6 +273,10 @@ func (f *File) doWrite(data []byte, off int64) (uint32, syscall.Errno) { if err == io.EOF { fileID, err = f.createHeader() fileWasEmpty = true + } else if err != nil { + // Other errors mean readFileID() found a corrupt header + tlog.Warn.Printf("doWrite %d: corrupt header: %v", f.qIno.Ino, err) + return 0, syscall.EIO } if err != nil { return 0, fs.ToErrno(err) From 8f3ec5dcaa6eb18d11746675190a7aaceb422764 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Tue, 21 Feb 2023 22:04:30 +0100 Subject: [PATCH 18/20] fusefrontend: unbreak isConsecutiveWrite streaming write optimization Commit 6196a5b5 got the logic inverted, hence we never set the last position markers. Fixes https://github.com/rfjakob/gocryptfs/issues/712 --- internal/fusefrontend/file.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/fusefrontend/file.go b/internal/fusefrontend/file.go index ff26a6e..8d0ba01 100644 --- a/internal/fusefrontend/file.go +++ b/internal/fusefrontend/file.go @@ -384,7 +384,7 @@ func (f *File) Write(ctx context.Context, data []byte, off int64) (uint32, sysca } } n, errno := f.doWrite(data, off) - if errno != 0 { + if errno == 0 { f.lastOpCount = openfiletable.WriteOpCount() f.lastWrittenOffset = off + int64(len(data)) - 1 } From 403f59b1c047db4106f504e7d042125f527e1e58 Mon Sep 17 00:00:00 2001 From: rfjakob Date: Sat, 25 Feb 2023 18:12:10 +0100 Subject: [PATCH 19/20] Update README.md Package has been removed from Fedora. https://github.com/rfjakob/gocryptfs/issues/659 --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index a896133..616af11 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,6 @@ distribution must be installed for mounting to work. gocryptfs is also available as a package in most distributions. Examples: * Debian, Ubuntu: `apt install gocryptfs` -* Fedora: `dnf install gocryptfs` * Arch: `pacman -S gocryptfs` * MacPorts: `port install gocryptfs` From 77a0410e2ed77cae279bf7a1bcbfff82dbf56e16 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 4 Mar 2023 13:49:48 +0100 Subject: [PATCH 20/20] README: update changelog for v2.3.1 --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 616af11..f19a3e7 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,20 @@ RM: 2,367 Changelog --------- +#### v2.3.1, 2023-03-04 +* Optimize NFS streaming write performance ([#712](https://github.com/rfjakob/gocryptfs/issues/712), + [commit](https://github.com/rfjakob/gocryptfs/commit/8f3ec5dcaa6eb18d11746675190a7aaceb422764)). + You should see about a 4x performance increase. +* Use `debug.ReadBuildInfo()` to provide some + version information even when not built with `build.bash` ([#701](https://github.com/rfjakob/gocryptfs/pull/701)) . +* Fix bug that caused the `logger` process to be killed when started from `xfce4-terminal`, + and that terminal window was closed ([#660](https://github.com/rfjakob/gocryptfs/issues/660), + [commit](https://github.com/rfjakob/gocryptfs/commit/ff32e9979130e6237b0d97ef88304fa79ce61b06)). +* MacOS: Fix reverse mount failing with `read-only file system` ([#690](https://github.com/rfjakob/gocryptfs/pull/690)) +* Make gocryptfs compile on riscv64 by switching from [jacobsa/crypto](https://github.com/jacobsa/crypto) + to maintained fork [aperturerobotics/jacobsa-crypto](https://github.com/aperturerobotics/jacobsa-crypto) + ([#674](https://github.com/rfjakob/gocryptfs/pull/674)) + #### v2.3.0, 2022-10-21 * Identical to v2.3, just tagged once more in full semver x.y.z format. This make Go's fetching logic happy, which ignores v2.3 (without the third digit) completely.