qemu/hw/9pfs
Greg Kurz 6482a96163 9pfs: introduce relative_openat_nofollow() helper
When using the passthrough security mode, symbolic links created by the
guest are actual symbolic links on the host file system.

Since the resolution of symbolic links during path walk is supposed to
occur on the client side. The server should hence never receive any path
pointing to an actual symbolic link. This isn't guaranteed by the protocol
though, and malicious code in the guest can trick the server to issue
various syscalls on paths whose one or more elements are symbolic links.
In the case of the "local" backend using the "passthrough" or "none"
security modes, the guest can directly create symbolic links to arbitrary
locations on the host (as per spec). The "mapped-xattr" and "mapped-file"
security modes are also affected to a lesser extent as they require some
help from an external entity to create actual symbolic links on the host,
i.e. another guest using "passthrough" mode for example.

The current code hence relies on O_NOFOLLOW and "l*()" variants of system
calls. Unfortunately, this only applies to the rightmost path component.
A guest could maliciously replace any component in a trusted path with a
symbolic link. This could allow any guest to escape a virtfs shared folder.

This patch introduces a variant of the openat() syscall that successively
opens each path element with O_NOFOLLOW. When passing a file descriptor
pointing to a trusted directory, one is guaranteed to be returned a
file descriptor pointing to a path which is beneath the trusted directory.
This will be used by subsequent patches to implement symlink-safe path walk
for any access to the backend.

Symbolic links aren't the only threats actually: a malicious guest could
change a path element to point to other types of file with undesirable
effects:
- a named pipe or any other thing that would cause openat() to block
- a terminal device which would become QEMU's controlling terminal

These issues can be addressed with O_NONBLOCK and O_NOCTTY.

Two helpers are introduced: one to open intermediate path elements and one
to open the rightmost path element.

Suggested-by: Jann Horn <jannh@google.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(renamed openat_nofollow() to relative_openat_nofollow(),
 assert path is relative and doesn't contain '//',
 fixed side-effect in assert, Greg Kurz)
Signed-off-by: Greg Kurz <groug@kaod.org>
2017-02-28 11:21:15 +01:00
..
9p-handle.c 9pfs: add cleanup operation for handle backend driver 2016-11-23 13:53:34 +01:00
9p-local.c 9pfs: remove side-effects in local_open() and local_opendir() 2017-02-28 11:21:14 +01:00
9p-posix-acl.c 9pfs: Clean up includes 2016-01-29 15:07:23 +00:00
9p-proxy.c 9pfs: add cleanup operation for proxy backend driver 2016-11-23 13:53:34 +01:00
9p-proxy.h Clean up ill-advised or unusual header guards 2016-07-12 16:20:46 +02:00
9p-synth.c 9p: synth: drop v9fs_ prefix 2016-07-01 14:38:54 +02:00
9p-synth.h 9pfs: fsdev: drop useless extern annotation for functions 2016-10-17 14:13:58 +02:00
9p-util.c 9pfs: introduce relative_openat_nofollow() helper 2017-02-28 11:21:15 +01:00
9p-util.h 9pfs: introduce relative_openat_nofollow() helper 2017-02-28 11:21:15 +01:00
9p-xattr-user.c 9pfs: Clean up includes 2016-01-29 15:07:23 +00:00
9p-xattr.c 9pfs: local: move xattr security ops to 9p-xattr.c 2017-02-28 11:21:14 +01:00
9p-xattr.h 9pfs: local: move xattr security ops to 9p-xattr.c 2017-02-28 11:21:14 +01:00
9p.c coroutine-lock: add mutex argument to CoQueue APIs 2017-02-21 11:39:40 +00:00
9p.h 9pfs: fix P9_NOTAG and P9_NOFID macros 2017-01-03 17:28:44 +01:00
codir.c 9pfs: use coroutine_fn annotation in hw/9pfs/co*.[ch] 2016-10-17 14:13:58 +02:00
cofile.c 9pfs: use coroutine_fn annotation in hw/9pfs/co*.[ch] 2016-10-17 14:13:58 +02:00
cofs.c 9pfs: use coroutine_fn annotation in hw/9pfs/co*.[ch] 2016-10-17 14:13:58 +02:00
coth.c coroutine: move entry argument to qemu_coroutine_create 2016-07-13 13:26:02 +02:00
coth.h 9pfs: use coroutine_fn annotation in hw/9pfs/co*.[ch] 2016-10-17 14:13:58 +02:00
coxattr.c 9pfs: use coroutine_fn annotation in hw/9pfs/co*.[ch] 2016-10-17 14:13:58 +02:00
Makefile.objs 9pfs: introduce relative_openat_nofollow() helper 2017-02-28 11:21:15 +01:00
trace-events 9pfs: limit xattr size in xattrcreate 2016-11-01 12:03:02 +01:00
virtio-9p-device.c 9pfs: introduce init_out/in_iov_from_pdu 2017-01-03 17:28:44 +01:00
virtio-9p.h 9pfs: introduce transport specific callbacks 2017-01-03 17:28:44 +01:00