Jakob Unterwurzacher
b22cc03c75
fusefrontend: -allow_other: set file mode *after* chown in Create()
...
Reported by @slackner at https://github.com/rfjakob/gocryptfs/issues/327 :
Possible race-conditions between file creation and Fchownat
* Assume a system contains a gocryptfs mount as root user
with -allow_other
* As a regular user create a new file with mode containing
the SUID flag and write access for other users
* Before gocryptfs executes the Fchownat call, try to open
the file again, write some exploit code to it, and try to run it.
For a short time, the file is owned by root and has the SUID flag, so
this is pretty dangerous.
2019-01-08 21:50:10 +01:00
Sebastian Lackner
4170ef00f3
syscallcompat: Implement workaround for Fchmodat with AT_SYMLINK_NOFOLLOW.
...
Fixes https://github.com/rfjakob/gocryptfs/issues/259
2019-01-07 23:07:53 +01:00
Jakob Unterwurzacher
8253c55386
tests: add Fchmodat test
...
Test that we handle symlinks correctly.
2019-01-07 23:07:53 +01:00
Sebastian Lackner
57a52d6aef
fusefrontend: Clarify access mode check related to O_WRONLY handling.
...
Use O_ACCMODE mask in openWriteOnlyFile for improved readability.
2019-01-07 21:25:23 +01:00
Sebastian Lackner
2332462e78
fusefrontend: Filter O_CREAT in mangleOpenFlags.
2019-01-07 21:19:13 +01:00
Sebastian Lackner
aa2fa24c42
fusefrontend: Check result of Fchmod syscall.
...
Fixes https://github.com/rfjakob/gocryptfs/issues/328
2019-01-06 21:00:17 +01:00
Sebastian Lackner
40d2427fd7
fusefrontend: Fix computation of cipherSz in Allocate FUSE call.
...
Do not use PlainSizeToCipherSize() since this adds the 18 bytes file header.
Partially fixes https://github.com/rfjakob/gocryptfs/issues/311
2019-01-06 20:56:59 +01:00
Jakob Unterwurzacher
5c8e7feabd
tests: check that fallocate does not over-allocate space
...
We currently allocate 18 bytes too much:
https://github.com/rfjakob/gocryptfs/issues/311
2019-01-06 20:56:53 +01:00
Jakob Unterwurzacher
c83aa417e4
tests: move fallocate tests to its own file
...
matrix_test.go is already too big.
2019-01-06 20:31:41 +01:00
Jakob Unterwurzacher
db425cab9e
tests: TestFallocate: comment what "d" and "h" means
...
Document what "d" and "h" means in the fancy ASCII diagrams.
https://github.com/rfjakob/gocryptfs/pull/326
2019-01-06 12:49:27 +01:00
Sebastian Lackner
8310dd95be
fusefrontend: Properly convert plaintext <-> ciphertext offsets in SeekData().
...
Fixes https://github.com/rfjakob/gocryptfs/issues/304
2019-01-06 12:21:54 +01:00
Jakob Unterwurzacher
bd055ed7de
Update changelog
2019-01-05 18:34:22 +01:00
Jakob Unterwurzacher
fb705f9978
tests: add parallel_cp stress test
...
Modeled after xfstests generic/273
https://github.com/rfjakob/gocryptfs/issues/322
2019-01-05 18:20:04 +01:00
Sebastian Lackner
7e05e809b7
main: Run 'ensure fds' code early during the program startup.
...
The files are apparently processed in alphabetic order, so cli_args.go is
processed before main.go. In order to run before the go-fuse imports, put
the 'ensure fds' code in a separate package. Debug messages are omitted
to avoid additional imports (that might contain other code messing up our
file descriptors).
2019-01-05 16:12:16 +01:00
Jakob Unterwurzacher
ad15ad9985
main: ensure fds 0,1,2 are always open
...
The Go stdlib, as well as the gocryptfs code, relies on the fact
that fds 0,1,2 are always open.
See https://github.com/rfjakob/gocryptfs/issues/320 for details.
2019-01-05 14:17:51 +01:00
Sebastian Lackner
5055f39bd5
fusefrontend: Allow to set/remove xattr on directory without read permission.
...
Setting/removing extended attributes on directories was partially fixed with
commit eff35e60b6
. However, on most file systems
it is also possible to do these operations without read access (see tests).
Since we cannot open a write-access fd to a directory, we have to use the
/proc/self/fd trick (already used for ListXAttr) for the other operations aswell.
For simplicity, let's separate the Linux and Darwin code again (basically revert
commit f320b76fd1
), and always use the
/proc/self/fd trick on Linux. On Darwin we use the best-effort approach with
openBackingFile() as a fallback.
More discussion about the available options is available in
https://github.com/rfjakob/gocryptfs/issues/308 .
2019-01-05 12:34:40 +01:00
Sebastian Lackner
f17721c364
A few more spelling fixes.
2019-01-05 12:27:55 +01:00
Jakob Unterwurzacher
8c35235c34
Add Makefile
...
We are going to use the Makefile to save useful commands
without creating too many shell scripts in the top dir.
2019-01-05 12:25:38 +01:00
Jakob Unterwurzacher
61a6b24d4e
doc: update extractloop results
...
Update output and add a nice plot.
2019-01-05 12:17:17 +01:00
Jakob Unterwurzacher
28139ca91d
doc: update XFSTESTS results
2019-01-05 12:06:00 +01:00
Jakob Unterwurzacher
65eded4a22
tests: bump maxCacheFds to 3
...
As the dirCache now has 3 entries, the tests should accept
up to 3 extra fds without declaring an fd leak.
2019-01-04 23:50:01 +01:00
Jakob Unterwurzacher
c32066c5b0
fusefrontend: fix fd leak in dirCache
...
The missing break meant that we may find a second
hit in the cache, Dup() a second fd, and leak the first
one.
Thanks @slackner for finding this.
2019-01-04 23:35:48 +01:00
Jakob Unterwurzacher
8074f12beb
nametransform: ReadDirIVAt: return raw syscall error
...
Otherwise this can happen, as triggered by xfstests generic/011:
go-fuse: can't convert error type: openat failed: too many open files
The app then gets a misleading "Function not implemented" error.
2019-01-04 23:21:27 +01:00
Jakob Unterwurzacher
3473a84963
fusefrontend: print warning when Create() runs out of file descriptors
...
We alread have this warning in Open(), but xfstests generic/488
causes "too many open files" via Create. Add the same message so
the user sees what is going on.
2019-01-04 23:15:04 +01:00
Jakob Unterwurzacher
eff35e60b6
fusefrontend: fix setting xattrs on directories
...
Directories cannot be opened read-write. Retry with RDONLY.
2019-01-04 22:22:24 +01:00
Jakob Unterwurzacher
3365cfc02b
fusefrontend: disable dirCache stats printing
...
This was inadvertedly kept enabled after benchmarking.
2019-01-04 22:07:02 +01:00
Sebastian Lackner
fab695fa60
Documentation: Fix MANPAGE-render.bash script.
2019-01-04 22:04:44 +01:00
Jakob Unterwurzacher
23b5c80a04
Update performance.txt
2019-01-04 22:04:14 +01:00
Jakob Unterwurzacher
c0a7a14cde
fusefrontend: upgrade to three-entry dirCache
...
3 entries should work well for up to three parallel users.
It works well for extractloop.bash (two parallel tar extracts).
2019-01-04 21:45:03 +01:00
Jakob Unterwurzacher
c1a2a36a79
fsck: don't misdetect a file hole at EOF
...
https://github.com/rfjakob/gocryptfs/issues/304 :
A second minor issue is that `if bytes.Equal(buf, allZero) {` compares the whole
buffer, although the last read could have been shorter. This could trigger the
"skip file hole" code at the end of a file although there isn't any hole to
skip.
2019-01-04 20:26:16 +01:00
Jakob Unterwurzacher
4b1d080673
Update gocryptfs-xray manpage, have MANPAGE-render.bash generate both
...
have MANPAGE-render.bash generate both gocryptfs.1 and gocryptfs-xray.1
2019-01-04 20:12:07 +01:00
Jakob Unterwurzacher
7f0de69fe2
Update changelog and gocryptfs-xray manpage
2019-01-04 20:12:07 +01:00
Sebastian Lackner
117dc3f2cc
fusefrontend_reverse: Fix redeclaration of 'entries' variable.
...
Go version go1.10.7 linux/amd64 complains with:
internal/fusefrontend_reverse/rfs.go:333: declaration of "entries" shadows
declaration at internal/fusefrontend_reverse/rfs.go:327
2019-01-04 20:11:45 +01:00
Jakob Unterwurzacher
2024616722
xray: print "assuming AES-GCM mode" unless -aessiv is passed
...
To alert the user that they can and should choose the
right mode.
2019-01-04 19:34:15 +01:00
Jakob Unterwurzacher
8c18fb5db9
file-format.md: document AES-SIV block layout
...
Fixes https://github.com/rfjakob/gocryptfs/issues/299
2019-01-04 19:31:41 +01:00
Jakob Unterwurzacher
28584d0d2c
xray: recreate test filesytems with -scrypt 10
...
Speeds up the dumpmasterkey test *a lot*:
Before:
ok github.com/rfjakob/gocryptfs/gocryptfs-xray/xray_tests 0.398s
After:
ok github.com/rfjakob/gocryptfs/gocryptfs-xray/xray_tests 0.023s
2019-01-04 19:31:08 +01:00
Jakob Unterwurzacher
8d71f8fe52
xray: add dumpmasterkey test
2019-01-04 19:21:09 +01:00
Jakob Unterwurzacher
44e860d105
xray: add support for inspecting AES-SIV files (-aessiv flag)
...
https://github.com/rfjakob/gocryptfs/issues/299 :
In GCM mode the auth tags are at the end of each block, but in
SIV mode the auth tags follow immediately after the nonce. As a
result, in AES-SIV mode the output of gocryptfs-xray is misleading
and does not actually print the auth tag, but just the last
16-byte of the ciphertext.
diff --git a/gocryptfs-xray/xray_main.go b/gocryptfs-xray/xray_main.go index 74c9fb3..5a81caf 100644 ---
a/gocryptfs-xray/xray_main.go +++ b/gocryptfs-xray/xray_main.go @@ -16,9 +16,10 @@ import (
)
const ( - ivLen = contentenc.DefaultIVBits / 8 - blockSize = contentenc.DefaultBS + ivLen + cryptocore.AuthTagLen - myName =
"gocryptfs-xray" + ivLen = contentenc.DefaultIVBits / 8 + authTagLen = cryptocore.AuthTagLen + blockSize = contentenc.DefaultBS +
ivLen + cryptocore.AuthTagLen + myName = "gocryptfs-xray"
)
func errExit(err error) { @@ -26,13 +27,18 @@ func errExit(err error) { os.Exit(1)
}
-func prettyPrintHeader(h *contentenc.FileHeader) { +func prettyPrintHeader(h *contentenc.FileHeader, aessiv bool) { id :=
hex.EncodeToString(h.ID)
- fmt.Printf("Header: Version: %d, Id: %s\n", h.Version, id) + msg := "Header: Version: %d, Id: %s" + if aessiv { + msg += ",
assuming AES-SIV mode" + } + fmt.Printf(msg+"\n", h.Version, id)
}
func main() { dumpmasterkey := flag.Bool("dumpmasterkey", false, "Decrypt and dump the master key") + aessiv :=
flag.Bool("aessiv", false, "Assume AES-SIV mode instead of AES-GCM")
flag.Parse() if flag.NArg() != 1 { fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS] FILE\n"+ @@ -54,7 +60,7 @@ func main() { if
*dumpmasterkey {
dumpMasterKey(fn)
} else {
- inspectCiphertext(fd) + inspectCiphertext(fd, *aessiv)
}
}
@@ -72,7 +78,7 @@ func dumpMasterKey(fn string) {
}
}
-func inspectCiphertext(fd *os.File) { +func inspectCiphertext(fd *os.File, aessiv bool) { headerBytes := make([]byte,
contentenc.HeaderLen) n, err := fd.ReadAt(headerBytes, 0) if err == io.EOF && n == 0 {
@@ -88,34 +94,30 @@ func inspectCiphertext(fd *os.File) { if err != nil { errExit(err)
}
- prettyPrintHeader(header) + prettyPrintHeader(header, aessiv) var i int64 + buf := make([]byte, blockSize) for i = 0; ;
i++ {
- blockLen := int64(blockSize) off := contentenc.HeaderLen + i*blockSize - iv := make([]byte, ivLen) - _, err := fd.ReadAt(iv, off)
- if err == io.EOF { - break - } else if err != nil { + n, err := fd.ReadAt(buf, off) + if err != nil && err != io.EOF {
errExit(err)
}
- tag := make([]byte, cryptocore.AuthTagLen) - _, err = fd.ReadAt(tag, off+blockSize-cryptocore.AuthTagLen) - if err == io.EOF { -
fi, err2 := fd.Stat() - if err2 != nil { - errExit(err2) - } - _, err2 = fd.ReadAt(tag, fi.Size()-cryptocore.AuthTagLen) - if err2
!= nil { - errExit(err2) - } - blockLen = (fi.Size() - contentenc.HeaderLen) % blockSize - } else if err != nil { - errExit(err) +
if n == 0 && err == io.EOF { + break + } + // A block contains at least the IV, the Auth Tag and 1 data byte + if n <
ivLen+authTagLen+1 { + errExit(fmt.Errorf("corrupt block: truncated data, len=%d", n)) + } + data := buf[:n] + // Parse block data +
iv := data[:ivLen] + tag := data[len(data)-authTagLen:] + if aessiv { + tag = data[ivLen : ivLen+authTagLen]
}
fmt.Printf("Block %2d: IV: %s, Tag: %s, Offset: %5d Len: %d\n", - i, hex.EncodeToString(iv),
hex.EncodeToString(tag), off, blockLen) + i, hex.EncodeToString(iv), hex.EncodeToString(tag), off, len(data))
}
}
diff --git a/gocryptfs-xray/xray_tests/aessiv_fs.masterkey.txt b/gocryptfs-xray/xray_tests/aessiv_fs.masterkey.txt new file mode
100644 index 0000000..70835ac --- /dev/null +++ b/gocryptfs-xray/xray_tests/aessiv_fs.masterkey.txt @@ -0,0 +1,5 @@ +Your master key
is: + + 29dd219d-e227ff20-8474469d-9fc9fdc6- + b434ab35-404e808c-489d441e-2c1003f2 + diff --git
a/gocryptfs-xray/xray_tests/aessiv_fs.xray.txt b/gocryptfs-xray/xray_tests/aessiv_fs.xray.txt new file mode 100644 index
0000000..6a48079 --- /dev/null +++ b/gocryptfs-xray/xray_tests/aessiv_fs.xray.txt @@ -0,0 +1,3 @@ +Header: Version: 2, Id:
c2f21142e108952a47edfe16053d2bb9, assuming AES-SIV mode +Block 0: IV: 7621fdc35be7671ac6f369214436e8ff, Tag:
e8108c158b22cad6bb3296645357eb75, Offset: 18 Len: 4128 +Block 1: IV: f096d86a4dc3461ef17655cfcf865b13, Tag:
925f23d647e4ab7add2c8d36362cc5a9, Offset: 4146 Len: 936 diff --git a/gocryptfs-xray/xray_tests/aessiv_fs/Ldq-c4ADpM5iGSSrPjUAqQ
b/gocryptfs-xray/xray_tests/aessiv_fs/Ldq-c4ADpM5iGSSrPjUAqQ new file mode 100644 index 0000000..bfd4dfe Binary files /dev/null and
b/gocryptfs-xray/xray_tests/aessiv_fs/Ldq-c4ADpM5iGSSrPjUAqQ differ diff --git a/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.conf
b/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.conf new file mode 100644 index 0000000..9b8b95f --- /dev/null +++
b/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.conf @@ -0,0 +1,21 @@ +{ + "Creator": "gocryptfs v1.7-beta1-7-g6b94f5e", +
"EncryptedKey": "D0kHfg/pryMO9Ydo15EwpYjNHf3iWKq2GJyNocbjwJt9blEeMoLD5DnoARuDzQs54hblw+9MHwFjCSHYmJrFbA==", + "ScryptObject": { +
"Salt": "ehn0LM/Hy/4QkXAMCZq3c3p0O9G7gu5e3OQSR8MiJ6c=", + "N": 65536, + "R": 8, + "P": 1, + "KeyLen": 32 + }, + "Version": 2, +
"FeatureFlags": [ + "GCMIV128", + "HKDF", + "DirIV", + "EMENames", + "LongNames", + "Raw64", + "AESSIV" + ] +} diff --git
a/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.diriv b/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.diriv new file mode 100644
index 0000000..dd57ce1 --- /dev/null +++ b/gocryptfs-xray/xray_tests/aessiv_fs/gocryptfs.diriv @@ -0,0 +1 @@ +.¨Í1Aiõ&Á4öÉ \
No newline at end of file diff --git a/gocryptfs-xray/xray_tests/xray_test.go b/gocryptfs-xray/xray_tests/xray_test.go index
a3374b0..8e5fc0c 100644 --- a/gocryptfs-xray/xray_tests/xray_test.go +++ b/gocryptfs-xray/xray_tests/xray_test.go @@ -24,3 +24,20 @@
func TestAesgcmXray(t *testing.T) {
fmt.Printf("have:\n%s", string(out))
}
}
+ +func TestAessivXray(t *testing.T) { + expected, err := ioutil.ReadFile("aessiv_fs.xray.txt") + if err != nil { + t.Fatal(err) + }
+ cmd := exec.Command("../gocryptfs-xray", "-aessiv", "aessiv_fs/Ldq-c4ADpM5iGSSrPjUAqQ") + out, err := cmd.CombinedOutput() + if
err != nil { + t.Fatal(err) + } + if bytes.Compare(out, expected) != 0 { + t.Errorf("Unexpected output") +
fmt.Printf("expected:\n%s", string(expected)) + fmt.Printf("have:\n%s", string(out)) + } +}
2019-01-04 19:10:36 +01:00
Jakob Unterwurzacher
30a8fda0a1
xray: add tests and example aes-gcm fs
...
The single test compares the gocryptfs-xray output with the expected output.
2019-01-04 19:02:36 +01:00
Jakob Unterwurzacher
cb524b60b4
Update changelog
2019-01-04 18:05:37 +01:00
Jakob Unterwurzacher
6b94f5ef51
reverse mode: -exclude: filter out excluded .name files
...
Fixes https://github.com/rfjakob/gocryptfs/issues/286 :
While the actual file is properly excluded, the * .name file is still leaked in the directory listing:
```
drwxr-xr-x 2 sebastian sebastian 4,0K Dez 17 14:58 .
drwxr-xr-x 7 sebastian sebastian 4,0K Dez 17 14:45 ..
-r-------- 1 sebastian sebastian 408 Dez 17 14:56 gocryptfs.conf
-r--r--r-- 1 sebastian sebastian 16 Dez 17 14:58 gocryptfs.diriv
-r--r--r-- 1 sebastian sebastian 320 Dez 17 14:58 gocryptfs.longname.3vZ_r3eDPb1_fL3j5VA4rd_bcKWLKT9eaxOVIGK5HFA.name
```
2019-01-04 17:59:00 +01:00
Jakob Unterwurzacher
58f62ada46
tests: reverse: verify that longname .name files are exluded as well
...
Currently fails, will be fixed in the next commit.
https://github.com/rfjakob/gocryptfs/issues/286
2019-01-04 17:57:57 +01:00
Jakob Unterwurzacher
75a3e2c2ee
reverse mode: fix "-exclude" in "-plaintextnames" dir listings
...
Excluded files showed up in directory listing like this:
drwxr-xr-x 2 sebastian sebastian 4,0K Dez 17 14:48 .
drwxr-xr-x 7 sebastian sebastian 4,0K Dez 17 14:45 ..
-????????? ? ? ? ? ? abcd
-r-------- 1 sebastian sebastian 366 Dez 17 14:45 gocryptfs.conf
Fixes https://github.com/rfjakob/gocryptfs/issues/285
2019-01-04 17:36:06 +01:00
Jakob Unterwurzacher
a2f83acc30
tests: fix VerifyExistence() helper, it missed unstat()able files
...
VerifyExistence missed unstat()able files in the directory listing
because ioutil.ReadDir() filtered them out.
https://github.com/rfjakob/gocryptfs/issues/285
2019-01-04 17:36:06 +01:00
Sebastian Lackner
cdb57ca7e0
fsck: Do not show files/directories without access permissions as corrupt.
...
When running as a regular user, error EACCES does not necessarily mean that the
file/directory/xattr is corrupt, but just that we do not have sufficient access
permissions. Add a hint that running as root can be used to check everything.
Fixes: https://github.com/rfjakob/gocryptfs/issues/309
2019-01-04 09:34:12 +01:00
Sebastian Lackner
acf7e52022
fusefrontend: Allow to create sparse file of size 4096.
...
When the old size is zero, there are no existing blocks to merge the
new data with. Directly use Ftruncate if the size is block-aligned.
Fixes https://github.com/rfjakob/gocryptfs/issues/305
2019-01-04 01:38:47 +01:00
Sebastian Lackner
ab169443fd
A few more spelling fixes.
...
Found with the 'codespell' utility.
2019-01-04 01:23:44 +01:00
Jakob Unterwurzacher
c1bd262600
Update README for v1.7-beta1
2019-01-03 20:38:36 +01:00
Jakob Unterwurzacher
7248669e27
travis: bump clone depth to 300
...
We are hitting the
fatal: No names found, cannot describe anything.
problem in the symlink_race branch.
2019-01-03 18:43:51 +01:00
Jakob Unterwurzacher
1c9fb707fe
tests: overengineer extractloop_plot_csv.m a little
...
Plot iteration time on second y axis, adjust line styles
2019-01-03 18:24:14 +01:00