Commit Graph

591 Commits

Author SHA1 Message Date
Alan Somers
3f2c630c74 fusefs: implement attribute cache timeouts
The FUSE protocol allows the server to specify the timeout period for the
client's attribute and entry caches.  This commit implements the timeout
period for the attribute cache.  The entry cache's timeout period is
currently disabled because it panics, and is guarded by the
vfs.fusefs.lookup_cache_expire sysctl.

PR:		235773
Reported by:	cem
Sponsored by:	The FreeBSD Foundation
2019-04-09 00:47:38 +00:00
Alan Somers
cad677915f fusefs: cache file attributes
FUSE_LOOKUP, FUSE_GETATTR, FUSE_SETATTR, FUSE_MKDIR, FUSE_LINK,
FUSE_SYMLINK, FUSE_MKNOD, and FUSE_CREATE all return file attributes with a
cache validity period.  fusefs will now cache the attributes, if the server
returns a non-zero cache validity period.

This change does _not_ implement finite attr cache timeouts.  That will
follow as part of PR 235773.

PR:		235775
Reported by:	cem
Sponsored by:	The FreeBSD Foundation
2019-04-08 18:45:41 +00:00
Alan Somers
caf5f57d2d fusefs: implement VOP_ACCESS
VOP_ACCESS was never fully implemented in fusefs.  This change:
* Removes the FACCESS_DO_ACCESS flag, which pretty much disabled the whole
  vop.
* Removes a quixotic special case for VEXEC on regular files.  I don't know
  why that was in there.
* Removes another confusing special case for VADMIN.
* Removes the FACCESS_NOCHECKSPY flag.  It seemed to be a performance
  optimization, but I'm unconvinced that it was a net positive.
* Updates test cases.

This change does NOT implement -o default_permissions.  That will be handled
separately.

PR:		236291
Sponsored by:	The FreeBSD Foundation
2019-04-05 18:37:48 +00:00
Alan Somers
efa23d9784 fusefs: enforce -onoallow_other even beneath the mountpoint
When -o allow_other is not in use, fusefs is supposed to prevent access to
the filesystem by any user other than the one who owns the daemon.  Our
fusefs implementation was only enforcing that restriction at the mountpoint
itself.  That was usually good enough because lookup usually descends from
the mountpoint.  However, there are cases when it doesn't, such as when
using openat relative to a file beneath the mountpoint.

PR:		237052
Sponsored by:	The FreeBSD Foundation
2019-04-05 17:21:23 +00:00
Alan Somers
140bb4927a fusefs: correctly return EROFS from VOP_ACCESS
Sponsored by:	The FreeBSD Foundation
2019-04-05 15:33:43 +00:00
Alan Somers
46c37cd0d7 fusefs: reenable some fsyncdir tests
These tests were actually fixed by r345398, r345390 and r345392, but I
neglected to reenable them.  Too bad googletest doesn't have the notion of
an Expected Failure like ATF does.

PR:		236474, 236473
Sponsored by:	The FreeBSD Foundation
2019-04-05 15:04:25 +00:00
Alan Somers
a7e81cb3db fusefs: properly handle FOPEN_KEEP_CACHE
If a fuse file system returne FOPEN_KEEP_CACHE in the open or create
response, then the client is supposed to _not_ clear its caches for that
file.  I don't know why clearing the caches would be the default given that
there's a separate flag to bypass the cache altogether, but that's the way
it is.  fusefs(5) will now honor this flag.

Our behavior is slightly different than Linux's because we reuse file
handles.  That means that open(2) wont't clear the cache if there's a
reusable file handle, even if the file server wouldn't have sent
FOPEN_KEEP_CACHE had we opened a new file handle like Linux does.

PR:		236560
Sponsored by:	The FreeBSD Foundation
2019-04-04 20:30:14 +00:00
Alan Somers
9a696dc6bb MFHead@r345880 2019-04-04 18:26:32 +00:00
Alan Somers
12292a99ac fusefs: correctly handle short writes
If a FUSE daemon returns FOPEN_DIRECT_IO when a file is opened, then it's
allowed to write less data than was requested during a FUSE_WRITE operation
on that file handle.  fusefs should simply return a short write to userland.

The old code attempted to resend the unsent data.  Not only was that
incorrect behavior, but it did it in an ineffective way, by attempting to
"rewind" the uio and uiomove the unsent data again.

This commit correctly handles short writes by returning directly to
userland if FOPEN_DIRECT_IO was set.  If it wasn't set (making the short
write technically a protocol violation), then we resend the unsent data.
But instead of rewinding the uio, just resend the data that's already in the
kernel.

That necessitated a few changes to fuse_ipc.c to reduce the amount of bzero
activity.  fusefs may be marginally faster as a result.

PR:		236381
Sponsored by:	The FreeBSD Foundation
2019-04-04 16:51:34 +00:00
Pawel Jakub Dawidek
d9eb18ace9 Implement tests for online expansion:
- init, init -R
- onetime, onetime -R
- 512 and 4k sectors
- encryption only
- encryption and authentication
- configure -r/-R for detached providers
- configure -r/-R for attached providers
- all keys allocated (10, 20 and 30MB provider sizes)
- keys allocated on demand (10, 20 and 30PB provider sizes)
- reading and writing to provider after expansion (10-30MB only)
- checking if metadata in old location is cleared.

Obtained from:	Fudo Security
2019-04-04 00:05:36 +00:00
Pawel Jakub Dawidek
1e560a0ca4 Update configure tests after addition of the online expansion.
Obtained from:	Fudo Security
2019-04-03 23:58:58 +00:00
Alan Somers
35cf0e7e56 fusefs: fix a panic in VOP_READDIR
The original fusefs import, r238402, contained a bug in fuse_vnop_close that
could close a directory's file handle while there were still other open file
descriptors.  The code looks deliberate, but there is no explanation for it.
This necessitated a workaround in fuse_vnop_readdir that would open a new
file handle if, "for some mysterious reason", that vnode didn't have any
open file handles.  r345781 had the effect of causing the workaround to
panic, making the problem more visible.

This commit removes the workaround and the original bug, which also fixes
the panic.

Sponsored by:	The FreeBSD Foundation
2019-04-03 20:57:43 +00:00
Alan Somers
9f10f423a9 fusefs: send FUSE_FLUSH during VOP_CLOSE
The FUSE protocol says that FUSE_FLUSH should be send every time a file
descriptor is closed.  That's not quite possible in FreeBSD because multiple
file descriptors can share a single struct file, and closef doesn't call
fo_close until the last close.  However, we can still send FUSE_FLUSH on
every VOP_CLOSE, which is probably good enough.

There are two purposes for FUSE_FLUSH.  One is to allow file systems to
return EIO if they have an error when writing data that's cached
server-side.  The other is to release POSIX file locks (which fusefs(5) does
not yet support).

PR:		236405, 236327
Sponsored by:	The FreeBSD Foundation
2019-04-03 19:59:45 +00:00
Alan Somers
e312493b37 fusefs: during ftruncate, discard cached data past truncation point
During truncate, fusefs was discarding entire cached blocks, but it wasn't
zeroing out the unused portion of a final partial block.  This resulted in
reads returning stale data.

PR:		233783
Reported by:	fsx
Sponsored by:	The FreeBSD Foundation
2019-04-03 02:29:56 +00:00
Alan Somers
4eb8481630 fusefs: check return value of wait(2) in fork tests
Reported by:	ngie
Sponsored by:	The FreeBSD Foundation
2019-04-02 18:44:01 +00:00
Alan Somers
99878c75e3 Respond to ngie's comments in D19752
Better Makefile syntax.

Note that this commit is to the project branch, but the review concerns the
merge to head.

Sponsored by:	The FreeBSD Foundation
2019-04-01 23:37:21 +00:00
Enji Cooper
8ac5aef8f3 Integrate capsicum-test into the FreeBSD test suite
This change takes capsicum-test from upstream and applies some local changes to make the
tests work on FreeBSD when executed via Kyua.

The local modifications are as follows:
1. Make `OpenatTest.WithFlag` pass with the new dot-dot lookup behavior in FreeBSD 12.x+.
2. capsicum-test references a set of helper binaries: `mini-me`, `mini-me.noexec`, and
   `mini-me.setuid`, as part of the execve/fexecve tests, via execve, fexecve, and open.
   It achieves this upstream by assuming `mini-me*` is in the current directory, however,
   in order for Kyua to execute `capsicum-test`, it needs to provide a full path to
   `mini-me*`. In order to achieve this, I made `capsicum-test` cache the executable's
   path from argv[0] in main(..) and use the cached value to compute the path to
   `mini-me*` as part of the execve/fexecve testcases.
3. The capsicum-test test suite assumes that it's always being run on CAPABILITIES enabled
   kernels. However, there's a chance that the test will be run on a host without a
   CAPABILITIES enabled kernel, so we must check for the support before running the tests.
   The way to achieve this is to add the relevant `feature_present("security_capabilities")`
   check to SetupEnvironment::SetUp() and skip the tests when the support is not available.
   While here, add a check for `kern.trap_enotcap` being enabled. As noted by markj@ in
   https://github.com/google/capsicum-test/issues/23, this sysctl being enabled can trigger
   non-deterministic failures. Therefore, the tests should be skipped if this sysctl is
   enabled.

All local changes have been submitted to the capsicum-test project
(https://github.com/google/capsicum-test) and are in various stages of review.
Please see the following pull requests for more details:
1. https://github.com/google/capsicum-test/pull/35
2. https://github.com/google/capsicum-test/pull/41
3. https://github.com/google/capsicum-test/pull/42

Reviewed by:	asomers
Discussed with:	emaste, markj
Approved by:	emaste (mentor)
MFC after:	2 months
Differential Revision: https://reviews.freebsd.org/D19758
2019-04-01 21:24:50 +00:00
Alan Somers
f8d4af104b fusefs: send FUSE_OPEN for every open(2) with unique credentials
By default, FUSE performs authorization in the server.  That means that it's
insecure for the client to reuse FUSE file handles between different users,
groups, or processes.  Linux handles this problem by creating a different
FUSE file handle for every file descriptor.  FreeBSD can't, due to
differences in our VFS design.

This commit adds credential information to each fuse_filehandle.  During
open(2), fusefs will now only reuse a file handle if it matches the exact
same access mode, pid, uid, and gid of the calling process.

PR:		236844
Sponsored by:	The FreeBSD Foundation
2019-04-01 20:42:15 +00:00
Alan Somers
363a74163b fusefs: allow opening files O_EXEC
O_EXEC is useful for fexecve(2) and fchdir(2).  Treat it as another fufh
type alongside the existing RDONLY, WRONLY, and RDWR.  Prior to r345742 this
would've caused a memory and performance penalty.

PR:		236329
Sponsored by:	The FreeBSD Foundation
2019-04-01 16:36:02 +00:00
Olivier Cochard
8f462da4f3 Fix and simplify code by using ATF_REQUIRE_FEATURE macro
PR:		236857
Reviewed by:	asomers, ngie
Approved by:	emaste
MFC after:	 1 month
Sponsored by:	Netflix
2019-04-01 14:21:32 +00:00
Alan Somers
208070583f fusefs: add another regression test for bug 236844
This test shows how bug 236844 can lead to a privilege escalation when used
with the -o allow_other mount option.

PR:		236844
Sponsored by:	The FreeBSD Foundation
2019-03-30 17:24:11 +00:00
Alan Somers
5fccbf313a fusefs: don't force direct io for files opened O_WRONLY
Previously fusefs would treat any file opened O_WRONLY as though the
FOPEN_DIRECT_IO flag were set, in an attempt to avoid issuing reads as part
of a RMW write operation on a cached part of the file.  However, the FUSE
protocol explicitly allows reads of write-only files for precisely that
reason.

Sponsored by:	The FreeBSD Foundation
2019-03-30 00:57:07 +00:00
Alan Somers
4b97bb009b fusefs: fix more tests when data caching is disabled
readahead is also disallowed when data_cache_mode=0.  This should've been
part of r345720.

Sponsored by:	The FreeBSD Foundation
2019-03-30 00:54:01 +00:00
Alan Somers
f3b5de2918 fusefs: fix tests when data caching is disabled
VOP_GETPAGES is disabled when vfs.fusefs.data_cache_mode=0, causing mmap to
return success but accessing the mapped memory will subsequently segfault.

Sponsored by:	The FreeBSD Foundation
2019-03-30 00:35:59 +00:00
Alan Somers
2d445be156 fusefs: test that open(2) can return a writable fd for a readonly file
Surprisingly, open(..., O_WRONLY | O_CREAT, 0444) should work.  POSIX
requires it.  But it didn't work in early FUSE implementations.  Add a
regression test so that our FUSE driver doesn't make the same mistake.

Sponsored by:	The FreeBSD Foundation
2019-03-29 21:52:10 +00:00
Alan Somers
61c225f92c fusefs: fix test build after r345645
It's no longer necessary to add GTESTS_CXXFLAGS to CXXFLAGS

Sponsored by:	The FreeBSD Foundation
2019-03-29 14:19:31 +00:00
Olivier Cochard
08e5c473f1 Skip test if feature security_capabilities is not available
PR:		236863
Approved by:	asomers
MFC after:	1 month
Sponsored by:	Netflix
2019-03-29 08:43:21 +00:00
Alan Somers
415e34c4d5 MFHead@r345677 2019-03-29 03:25:20 +00:00
Olivier Cochard
7d757b71bf Skip this test if if_tap module is not available
PR:		236842
Approved by:	asomers
MFC after:	1 month
Sponsored by:	Netflix
2019-03-28 16:17:33 +00:00
Alan Somers
42d50d16e2 fusefs: add a regression test for bug 236844
fusefs should send a FUSE_OPEN for every open(2) so the daemon can validate
accesses.

PR:		236844
Sponsored by:	The FreeBSD Foundation
2019-03-28 03:30:04 +00:00
Alan Somers
09c01e67de fusefs: deduplicate code in the allow_other test
Sponsored by:	The FreeBSD Foundation
2019-03-28 01:12:44 +00:00
Alan Somers
126769b7d1 fusefs: fix a resource leak in the allow_other tests
Sponsored by:	The FreeBSD Foundation
2019-03-28 00:25:57 +00:00
Alan Somers
477c462834 fusefs: correct mmap()'s return value in the allow_other test
Also, properly cleanup the semaphore.

Reported by:	ngie
Sponsored by:	The FreeBSD Foundation
2019-03-27 03:02:54 +00:00
Alan Somers
e0bec057db fusefs: correctly set fuse_release_in.flags in an error path
fuse_vnop_create must close the newly created file if it can't allocate a
vnode.  When it does so, it must use the same file flags for FUSE_RELEASE as
it used for FUSE_OPEN or FUSE_CREATE.

Reported by:	Coverity
Coverity CID:	1066204
Sponsored by:	The FreeBSD Foundation
2019-03-27 02:57:59 +00:00
Alan Somers
4a4282cb06 FUSEFS: during FUSE_READDIR, set the read size correctly.
The old formula was unnecessarily restrictive.

Sponsored by:	The FreeBSD Foundation
2019-03-27 02:01:34 +00:00
Alan Somers
13eaa5fadc fusefs: fix a race condition in the allow_other test
The test could occasionally hang if the parent's SIGUSR2 signal arrived
before the child had pause()d.  Using POSIX semaphores precludes that
possibility.

Sponsored by:	The FreeBSD Foundation
2019-03-27 00:24:57 +00:00
Kristof Provost
dcccc93ae4 pf tests: Fix accidental duplication of content
Also use the correct name for the scapy test script.
2019-03-23 01:07:51 +00:00
Alan Somers
19ef317d62 fusefs: fallback to MKNOD/OPEN if a filesystem doesn't support CREATE
If a FUSE filesystem returns ENOSYS for FUSE_CREATE, then fallback to
FUSE_MKNOD/FUSE_OPEN.

Also, fix a memory leak in the error path of fuse_vnop_create.  And do a
little cleanup in fuse_vnop_open.

PR:		199934
Reported by:	samm@os2.kiev.ua
Sponsored by:	The FreeBSD Foundation
2019-03-23 00:22:29 +00:00
Alan Somers
bf4d70841f fusefs: support VOP_MKNOD
PR:		236236
Sponsored by:	The FreeBSD Foundation
2019-03-22 19:08:48 +00:00
Kristof Provost
7de4bd92b8 pf tests: Test CVE-2019-5598
Verify that pf correctly drops inconsistent ICMP packets (i.e. where the
IP src/dst do not match the IP src/dst in the ICMP packet.
2019-03-22 07:39:28 +00:00
Alan Somers
6248288e97 fusefs: correctly handle cacheable negative LOOKUP responses
The FUSE protocol allows for LOOKUP to return a cacheable negative response,
which means that the file doesn't exist and the kernel can cache its
nonexistence.  As of this commit fusefs doesn't cache the nonexistence, but
it does correctly handle such responses.  Prior to this commit attempting to
create a file, even with O_CREAT would fail with ENOENT if the daemon
returned a cacheable negative response.

PR:		236231
Sponsored by:	The FreeBSD Foundation
2019-03-21 23:31:10 +00:00
Alan Somers
915012e0d0 fusefs: Don't treat fsync the same as fdatasync
For an unknown reason, fusefs was _always_ sending the fdatasync operation
instead of fsync.  Now it correctly sends one or the other.

Also, remove the Fsync.fsync_metadata_only test, along with the recently
removed Fsync.nop.  They should never have been added.  The kernel shouldn't
keep track of which files have dirty data; that's the daemon's job.

PR:		236473
Sponsored by:	The FreeBSD Foundation
2019-03-21 23:01:56 +00:00
Alan Somers
cc34f2f66a fusefs: VOP_FSYNC should be synchronous
returning asynchronously pretty much defeats the point of fsync

PR:		236474
Sponsored by:	The FreeBSD Foundation
2019-03-21 21:53:55 +00:00
Alan Somers
44dc9245e7 fusefs: don't check for the fusefs module during the tests
It's sufficient to check for /dev/fuse.  And due to bug 236647, the module
could be named either fuse or fusefs.

PR:		236647
Sponsored by:	The FreeBSD Foundation
2019-03-21 21:41:07 +00:00
Alan Somers
91ff3a0d3d fusefs: add a test case for the allow_other mount option
Also, fix one of the default_permissions test cases.  I forgot the
expectation for FUSE_ACCESS, because that doesn't work right now.

Sponsored by:	The FreeBSD Foundation
2019-03-21 19:56:33 +00:00
Kristof Provost
d1805f60af pf tests: Move Sniffer to its own file
Make it easier to re-use the sniffer class in other test support
scripts.
2019-03-21 08:15:46 +00:00
Alan Somers
9821f1d323 fusefs: adapt the tests to the fuse => fusefs rename
Sponsored by:	The FreeBSD Foundation
2019-03-21 00:11:43 +00:00
Alan Somers
f9856d0813 MFHead @345353 2019-03-20 23:32:37 +00:00
Alan Somers
4f1543f359 fuse(4): use GTEST_SKIP in the tests
Now the entire fuse test suite can "pass", or at least not fail.  Skipped
tests are reported to Kyua as passes, because googletest is still using
Kyua's plain test adapter.

Sponsored by:	The FreeBSD Foundation
2019-03-20 20:36:46 +00:00
Alan Somers
197f8aac00 fuse(4): fix a race condition in the tests
Sometimes the fuse daemon doesn't die as soon as its /dev/fuse file
descriptor is closed; it needs to be unmounted first.

Sponsored by:	The FreeBSD Foundation
2019-03-20 16:08:07 +00:00