Skip to content

Commit

Permalink
reverse: reject too-long symlink target reads with ENAMETOOLONG
Browse files Browse the repository at this point in the history
If the symlink target gets too long due to base64 encoding, we should
return ENAMETOOLONG instead of having the kernel reject the data and
returning an I/O error to the user.

Fixes #167
  • Loading branch information
rfjakob committed Nov 26, 2017
1 parent 9068721 commit 1bb47b6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
6 changes: 6 additions & 0 deletions internal/fusefrontend_reverse/rfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,5 +319,11 @@ func (rfs *ReverseFS) Readlink(cipherPath string, context *fuse.Context) (string
// Symlinks are encrypted like file contents and base64-encoded
cBinTarget := rfs.contentEnc.EncryptBlockNonce([]byte(plainTarget), 0, nil, nonce)
cTarget := rfs.nameTransform.B64.EncodeToString(cBinTarget)
// The kernel will reject a symlink target above 4096 chars and return
// and I/O error to the user. Better emit the proper error ourselves.
const PATH_MAX = 4096 // not defined on Darwin
if len(cTarget) > PATH_MAX {
return "", fuse.Status(syscall.ENAMETOOLONG)
}
return cTarget, fuse.OK
}
22 changes: 22 additions & 0 deletions tests/reverse/correctness_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,25 @@ func TestEnoent(t *testing.T) {
t.Errorf("want ENOENT, got: %v", err)
}
}

// If the symlink target gets too long due to base64 encoding, we should
// return ENAMETOOLONG instead of having the kernel reject the data and
// returning an I/O error to the user.
// https://github.com/rfjakob/gocryptfs/issues/167
func TestTooLongSymlink(t *testing.T) {
fn := dirA + "/TooLongSymlink"
target := string(bytes.Repeat([]byte("x"), 4000))
err := os.Symlink(target, fn)
if err != nil {
t.Fatal(err)
}
_, err = os.Readlink(dirC + "/TooLongSymlink")
if err == nil {
return
}
err2 := err.(*os.PathError)
if err2.Err != syscall.ENAMETOOLONG {
t.Errorf("Expected %q error, got %q instead", syscall.ENAMETOOLONG,
err2.Err)
}
}

0 comments on commit 1bb47b6

Please sign in to comment.