summaryrefslogtreecommitdiff
path: root/hw/9pfs
AgeCommit message (Collapse)AuthorFilesLines
2017-09-209pfs: check the size of transport buffer before marshalingJan Dakinevich1-3/+12
v9fs_do_readdir_with_stat() should check for a maximum buffer size before an attempt to marshal gathered data. Otherwise, buffers assumed as misconfigured and the transport would be broken. The patch brings v9fs_do_readdir_with_stat() in conformity with v9fs_do_readdir() behavior. Signed-off-by: Jan Dakinevich <jan.dakinevich@gmail.com> [groug, regression caused my commit 8d37de41cab1 # 2.10] Signed-off-by: Greg Kurz <groug@kaod.org>
2017-09-209pfs: fix name_to_path assertion in v9fs_complete_rename()Jan Dakinevich1-14/+9
The third parameter of v9fs_co_name_to_path() must not contain `/' character. The issue is most likely related to 9p2000.u protocol only. Signed-off-by: Jan Dakinevich <jan.dakinevich@gmail.com> [groug, regression caused by commit f57f5878578a # 2.10] Signed-off-by: Greg Kurz <groug@kaod.org>
2017-09-209pfs: fix readdir() for 9p2000.uJan Dakinevich1-13/+9
If the client is using 9p2000.u, the following occurs: $ cd ${virtfs_shared_dir} $ mkdir -p a/b/c $ ls a/b ls: cannot access 'a/b/a': No such file or directory ls: cannot access 'a/b/b': No such file or directory a b c instead of the expected: $ ls a/b c This is a regression introduced by commit f57f5878578a; local_name_to_path() now resolves ".." and "." in paths, and v9fs_do_readdir_with_stat()->stat_to_v9stat() then copies the basename of the resulting path to the response. With the example above, this means that "." and ".." are turned into "b" and "a" respectively... stat_to_v9stat() currently assumes it is passed a full canonicalized path and uses it to do two different things: 1) to pass it to v9fs_co_readlink() in case the file is a symbolic link 2) to set the name field of the V9fsStat structure to the basename part of the given path It only has two users: v9fs_stat() and v9fs_do_readdir_with_stat(). v9fs_stat() really needs 1) and 2) to be performed since it starts with the full canonicalized path stored in the fid. It is different for v9fs_do_readdir_with_stat() though because the name we want to put into the V9fsStat structure is the d_name field of the dirent actually (ie, we want to keep the "." and ".." special names). So, we only need 1) in this case. This patch hence adds a basename argument to stat_to_v9stat(), to be used to set the name field of the V9fsStat structure, and moves the basename logic to v9fs_stat(). Signed-off-by: Jan Dakinevich <jan.dakinevich@gmail.com> (groug, renamed old name argument to path and updated changelog) Signed-off-by: Greg Kurz <groug@kaod.org>
2017-09-059pfs: local: clarify fchmodat_nofollow() implementationGreg Kurz1-4/+8
Since fchmodat(2) on Linux doesn't support AT_SYMLINK_NOFOLLOW, we have to implement it using workarounds. There are two different ways, depending on whether the system supports O_PATH or not. In the case O_PATH is supported, we rely on the behavhior of openat(2) when passing O_NOFOLLOW | O_PATH and the file is a symbolic link. Even if openat_file() already adds O_NOFOLLOW to the flags, this patch makes it explicit that we need both creation flags to obtain the expected behavior. This is only cleanup, no functional change. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2017-09-059pfs: avoid sign conversion error simplifying the codePhilippe Mathieu-Daudé1-4/+2
(note this is how other functions also handle the errors). hw/9pfs/9p.c:948:18: warning: Loss of sign in implicit conversion offset = err; ^~~ Reported-by: Clang Static Analyzer Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Greg Kurz <groug@kaod.org>
2017-08-309pfs: fix dependenciesCornelia Huck1-1/+1
Nothing in fsdev/ or hw/9pfs/ depends on pci; it should rather depend on CONFIG_VIRTFS and CONFIG_VIRTIO/CONFIG_XEN only. Acked-by: Greg Kurz <groug@kaod.org> Reviewed-by: Thomas Huth <thuth@redhat.com> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2017-08-109pfs: local: fix fchmodat_nofollow() limitationsGreg Kurz2-16/+50
This function has to ensure it doesn't follow a symlink that could be used to escape the virtfs directory. This could be easily achieved if fchmodat() on linux honored the AT_SYMLINK_NOFOLLOW flag as described in POSIX, but it doesn't. There was a tentative to implement a new fchmodat2() syscall with the correct semantics: https://patchwork.kernel.org/patch/9596301/ but it didn't gain much momentum. Also it was suggested to look at an O_PATH based solution in the first place. The current implementation covers most use-cases, but it notably fails if: - the target path has access rights equal to 0000 (openat() returns EPERM), => once you've done chmod(0000) on a file, you can never chmod() again - the target path is UNIX domain socket (openat() returns ENXIO) => bind() of UNIX domain sockets fails if the file is on 9pfs The solution is to use O_PATH: openat() now succeeds in both cases, and we can ensure the path isn't a symlink with fstat(). The associated entry in "/proc/self/fd" can hence be safely passed to the regular chmod() syscall. The previous behavior is kept for older systems that don't have O_PATH. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com> Tested-by: Zhi Yong Wu <zhiyong.wu@ucloud.cn> Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2017-07-31docs: fix broken paths to docs/devel/tracing.txtPhilippe Mathieu-Daudé1-1/+1
With the move of some docs/ to docs/devel/ on ac06724a71, no references were updated. Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2017-07-13Convert error_report() to warn_report()Alistair Francis1-1/+1
Convert all uses of error_report("warning:"... to use warn_report() instead. This helps standardise on a single method of printing warnings to the user. All of the warnings were changed using these two commands: find ./* -type f -exec sed -i \ 's|error_report(".*warning[,:] |warn_report("|Ig' {} + Indentation fixed up manually afterwards. The test-qdev-global-props test case was manually updated to ensure that this patch passes make check (as the test cases are case sensitive). Signed-off-by: Alistair Francis <alistair.francis@xilinx.com> Suggested-by: Thomas Huth <thuth@redhat.com> Cc: Jeff Cody <jcody@redhat.com> Cc: Kevin Wolf <kwolf@redhat.com> Cc: Max Reitz <mreitz@redhat.com> Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Peter Lieven <pl@kamp.de> Cc: Josh Durgin <jdurgin@redhat.com> Cc: "Richard W.M. Jones" <rjones@redhat.com> Cc: Markus Armbruster <armbru@redhat.com> Cc: Peter Crosthwaite <crosthwaite.peter@gmail.com> Cc: Richard Henderson <rth@twiddle.net> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> Cc: Greg Kurz <groug@kaod.org> Cc: Rob Herring <robh@kernel.org> Cc: Peter Maydell <peter.maydell@linaro.org> Cc: Peter Chubb <peter.chubb@nicta.com.au> Cc: Eduardo Habkost <ehabkost@redhat.com> Cc: Marcel Apfelbaum <marcel@redhat.com> Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Igor Mammedov <imammedo@redhat.com> Cc: David Gibson <david@gibson.dropbear.id.au> Cc: Alexander Graf <agraf@suse.de> Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Jason Wang <jasowang@redhat.com> Cc: Marcelo Tosatti <mtosatti@redhat.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Cornelia Huck <cohuck@redhat.com> Cc: Stefan Hajnoczi <stefanha@redhat.com> Acked-by: David Gibson <david@gibson.dropbear.id.au> Acked-by: Greg Kurz <groug@kaod.org> Acked-by: Cornelia Huck <cohuck@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed by: Peter Chubb <peter.chubb@data61.csiro.au> Acked-by: Max Reitz <mreitz@redhat.com> Acked-by: Marcel Apfelbaum <marcel@redhat.com> Message-Id: <e1cfa2cd47087c248dd24caca9c33d9af0c499b0.1499866456.git.alistair.francis@xilinx.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-06-299pfs: handle transport errors in pdu_complete()Greg Kurz1-8/+15
Contrary to what is written in the comment, a buggy guest can misconfigure the transport buffers and pdu_marshal() may return an error. If this ever happens, it is up to the transport layer to handle the situation (9P is transport agnostic). This fixes Coverity issue CID1348518. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-29xen-9pfs: disconnect if buffers are misconfiguredStefano Stabellini1-21/+64
Implement xen_9pfs_disconnect by unbinding the event channels. On xen_9pfs_free, call disconnect if any event channels haven't been disconnected. If the frontend misconfigured the buffers set the backend to "Closing" and disconnect it. Misconfigurations include requesting a read of more bytes than available on the ring buffer, or claiming to be writing more data than available on the ring buffer. Signed-off-by: Stefano Stabellini <stefano@aporeto.com> Signed-off-by: Greg Kurz <groug@kaod.org>
2017-06-29virtio-9p: break device if buffers are misconfiguredGreg Kurz4-7/+40
The 9P protocol is transport agnostic: if the guest misconfigured the buffers, the best we can do is to set the broken flag on the device. Signed-off-by: Greg Kurz <groug@kaod.org>
2017-06-29virtio-9p: message header is 7-byte longGreg Kurz2-5/+8
The 9p spec at http://man.cat-v.org/plan_9/5/intro reads: "Each 9P message begins with a four-byte size field specify- ing the length in bytes of the complete message including the four bytes of the size field itself. The next byte is the message type, one of the constants in the enumeration in the include file <fcall.h>. The next two bytes are an iden- tifying tag, described below." ie, each message starts with a 7-byte long header. The core 9P code already assumes this pretty much everywhere. This patch does the following: - makes the assumption explicit in the common 9p.h header, since it isn't related to the transport - open codes the header size in handle_9p_output() and hardens the sanity check on the space needed for the reply message Signed-off-by: Greg Kurz <groug@kaod.org> Acked-by: Stefano Stabellini <sstabellini@kernel.org>
2017-06-29virtio-9p: record element after sanity checksGreg Kurz1-1/+2
If the guest sends a malformed request, we end up with a dangling pointer in V9fsVirtioState. This doesn't seem to cause any bug, but let's remove this side effect anyway. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
2017-06-299pfs: replace g_malloc()+memcpy() with g_memdup()Marc-André Lureau1-2/+1
I found these pattern via grepping the source tree. I don't have a coccinelle script for it! Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-06-299pfs: local: Add support for custom fmode/dmode in 9ps mapped security modesTobias Schramm2-4/+24
In mapped security modes, files are created with very restrictive permissions (600 for files and 700 for directories). This makes file sharing between virtual machines and users on the host rather complicated. Imagine eg. a group of users that need to access data produced by processes on a virtual machine. Giving those users access to the data will be difficult since the group access mode is always 0. This patch makes the default mode for both files and directories configurable. Existing setups that don't know about the new parameters keep using the current secure behavior. Signed-off-by: Tobias Schramm <tobleminer@gmail.com> Signed-off-by: Greg Kurz <groug@kaod.org>
2017-06-299pfs: local: remove: use correct path componentBruce Rogers1-1/+1
Commit a0e640a8 introduced a path processing error. Pass fstatat the dirpath based path component instead of the entire path. Signed-off-by: Bruce Rogers <brogers@suse.com> Signed-off-by: Greg Kurz <groug@kaod.org>
2017-05-259pfs: local: metadata file for the VirtFS rootGreg Kurz1-27/+59
When using the mapped-file security, credentials are stored in a metadata directory located in the parent directory. This is okay for all paths with the notable exception of the root path, since we don't want and probably can't create a metadata directory above the virtfs directory on the host. This patch introduces a dedicated metadata file, sitting in the virtfs root for this purpose. It relies on the fact that the "." name necessarily refers to the virtfs root. As for the metadata directory, we don't want the client to see this file. The current code only cares for readdir() but there are many other places to fix actually. The filtering logic is hence put in a separate function. Before: # ls -ld drwxr-xr-x. 3 greg greg 4096 May 5 12:49 . # chown root.root . chown: changing ownership of '.': Is a directory # ls -ld drwxr-xr-x. 3 greg greg 4096 May 5 12:49 . After: # ls -ld drwxr-xr-x. 3 greg greg 4096 May 5 12:49 . # chown root.root . # ls -ld drwxr-xr-x. 3 root root 4096 May 5 12:50 . and from the host: ls -al .virtfs_metadata_root -rwx------. 1 greg greg 26 May 5 12:50 .virtfs_metadata_root $ cat .virtfs_metadata_root virtfs.uid=0 virtfs.gid=0 Reported-by: Leo Gaspard <leo@gaspard.io> Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com> Tested-by: Leo Gaspard <leo@gaspard.io> [groug: work around a patchew false positive in local_set_mapped_file_attrat()]
2017-05-259pfs: local: simplify file openingGreg Kurz3-50/+29
The logic to open a path currently sits between local_open_nofollow() and the relative_openat_nofollow() helper, which has no other user. For the sake of clarity, this patch moves all the code of the helper into its unique caller. While here we also: - drop the code to skip leading "/" because the backend isn't supposed to pass anything but relative paths without consecutive slashes. The assert() is kept because we really don't want a buggy backend to pass an absolute path to openat(). - use strchrnul() to get a simpler code. This is ok since virtfs is for linux+glibc hosts only. - don't dup() the initial directory and add an assert() to ensure we don't return the global mountfd to the caller. BTW, this would mean that the caller passed an empty path, which isn't supposed to happen either. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com> [groug: fixed typos in changelog]
2017-05-259pfs: local: resolve special directories in pathsGreg Kurz1-7/+25
When using the mapped-file security mode, the creds of a path /foo/bar are stored in the /foo/.virtfs_metadata/bar file. This is okay for all paths unless they end with '.' or '..', because we cannot create the corresponding file in the metadata directory. This patch ensures that '.' and '..' are resolved in all paths. The core code only passes path elements (no '/') to the backend, with the notable exception of the '/' path, which refers to the virtfs root. This patch preserves the current behavior of converting it to '.' so that it can be passed to "*at()" syscalls ('/' would mean the host root). Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com>
2017-05-259pfs: check return value of v9fs_co_name_to_path()Greg Kurz1-11/+25
These v9fs_co_name_to_path() call sites have always been around. I guess no care was taken to check the return value because the name_to_path operation could never fail at the time. This is no longer true: the handle and synth backends can already fail this operation, and so will the local backend soon. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com>
2017-05-259pfs: assume utimensat() and futimens() are presentGreg Kurz1-5/+0
The utimensat() and futimens() syscalls have been around for ages (ie, glibc 2.6 and linux 2.6.22), and the decision was already taken to switch to utimensat() anyway when fixing CVE-2016-9602 in 2.9. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com>
2017-05-259pfs: local: fix unlink of alien files in mapped-file modeGreg Kurz1-19/+15
When trying to remove a file from a directory, both created in non-mapped mode, the file remains and EBADF is returned to the guest. This is a regression introduced by commit "df4938a6651b 9pfs: local: unlinkat: don't follow symlinks" when fixing CVE-2016-9602. It changed the way we unlink the metadata file from ret = remove("$dir/.virtfs_metadata/$name"); if (ret < 0 && errno != ENOENT) { /* Error out */ } /* Ignore absence of metadata */ to fd = openat("$dir/.virtfs_metadata") unlinkat(fd, "$name") if (ret < 0 && errno != ENOENT) { /* Error out */ } /* Ignore absence of metadata */ If $dir was created in non-mapped mode, openat() fails with ENOENT and we pass -1 to unlinkat(), which fails in turn with EBADF. We just need to check the return of openat() and ignore ENOENT, in order to restore the behaviour we had with remove(). Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com> [groug: rewrote the comments as suggested by Eric]
2017-05-259pfs: drop pdu_push_and_notify()Greg Kurz1-6/+1
Only pdu_complete() needs to notify the client that a request has completed. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-05-25virtio-9p/xen-9p: move 9p specific bits to core 9p codeGreg Kurz4-14/+10
These bits aren't related to the transport so let's move them to the core code. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2017-05-18Merge remote-tracking branch 'quintela/tags/migration/20170517' into stagingStefan Hajnoczi1-1/+1
migration/next for 20170517 # gpg: Signature made Wed 17 May 2017 11:46:36 AM BST # gpg: using RSA key 0xF487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" # gpg: aka "Juan Quintela <quintela@trasno.org>" # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * quintela/tags/migration/20170517: migration: Move check_migratable() into qdev.c migration: Move postcopy stuff to postcopy-ram.c migration: Move page_cache.c to migration/ migration: Create migration/blocker.h ram: Rename RAM_SAVE_FLAG_COMPRESS to RAM_SAVE_FLAG_ZERO migration: Pass Error ** argument to {save,load}_vmstate migration: Fix regression with compression threads Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2017-05-17migration: Create migration/blocker.hJuan Quintela1-1/+1
This allows us to remove lots of includes of migration/migration.h Signed-off-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2017-05-16xen: call qemu_set_cloexec instead of fcntlStefano Stabellini1-1/+1
Use the common utility function, which contains checks on return values and first calls F_GETFD as recommended by POSIX.1-2001, instead of manually calling fcntl. CID: 1374831 Signed-off-by: Stefano Stabellini <sstabellini@kernel.org> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Greg Kurz <groug@kaod.org> CC: anthony.perard@citrix.com CC: groug@kaod.org CC: aneesh.kumar@linux.vnet.ibm.com CC: Eric Blake <eblake@redhat.com>
2017-05-16xen/9pfs: fix two resource leaks on error paths, discovered by CoverityStefano Stabellini1-0/+2
CID: 1374836 Signed-off-by: Stefano Stabellini <sstabellini@kernel.org> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Greg Kurz <groug@kaod.org> CC: anthony.perard@citrix.com CC: groug@kaod.org CC: aneesh.kumar@linux.vnet.ibm.com
2017-05-159pfs: local: forbid client access to metadata (CVE-2017-7493)Greg Kurz1-2/+56
When using the mapped-file security mode, we shouldn't let the client mess with the metadata. The current code already tries to hide the metadata dir from the client by skipping it in local_readdir(). But the client can still access or modify it through several other operations. This can be used to escalate privileges in the guest. Affected backend operations are: - local_mknod() - local_mkdir() - local_open2() - local_symlink() - local_link() - local_unlinkat() - local_renameat() - local_rename() - local_name_to_path() Other operations are safe because they are only passed a fid path, which is computed internally in local_name_to_path(). This patch converts all the functions listed above to fail and return EINVAL when being passed the name of the metadata dir. This may look like a poor choice for errno, but there's no such thing as an illegal path name on Linux and I could not think of anything better. This fixes CVE-2017-7493. Reported-by: Leo Gaspard <leo@gaspard.io> Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com>
2017-04-26Merge remote-tracking branch 'remotes/sstabellini/tags/xen-20170421-v2-tag' ↵Peter Maydell5-5/+469
into staging Xen 2017/04/21 + fix # gpg: Signature made Tue 25 Apr 2017 19:10:37 BST # gpg: using RSA key 0x894F8F4870E1AE90 # gpg: Good signature from "Stefano Stabellini <stefano.stabellini@eu.citrix.com>" # gpg: aka "Stefano Stabellini <sstabellini@kernel.org>" # Primary key fingerprint: D04E 33AB A51F 67BA 07D3 0AEA 894F 8F48 70E1 AE90 * remotes/sstabellini/tags/xen-20170421-v2-tag: (21 commits) move xen-mapcache.c to hw/i386/xen/ move xen-hvm.c to hw/i386/xen/ move xen-common.c to hw/xen/ add xen-9p-backend to MAINTAINERS under Xen xen/9pfs: build and register Xen 9pfs backend xen/9pfs: send responses back to the frontend xen/9pfs: implement in/out_iov_from_pdu and vmarshal/vunmarshal xen/9pfs: receive requests from the frontend xen/9pfs: connect to the frontend xen/9pfs: introduce Xen 9pfs backend 9p: introduce a type for the 9p header xen: import ring.h from xen configure: use pkg-config for obtaining xen version xen: additionally restrict xenforeignmemory operations xen: use libxendevice model to restrict operations xen: use 5 digit xen versions xen: use libxendevicemodel when available configure: detect presence of libxendevicemodel xen: create wrappers for all other uses of xc_hvm_XXX() functions xen: rename xen_modified_memory() to xen_hvm_modified_memory() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-25xen/9pfs: build and register Xen 9pfs backendStefano Stabellini1-0/+1
Signed-off-by: Stefano Stabellini <stefano@aporeto.com> Reviewed-by: Greg Kurz <groug@kaod.org> CC: anthony.perard@citrix.com CC: jgross@suse.com CC: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> CC: Greg Kurz <groug@kaod.org>
2017-04-25xen/9pfs: send responses back to the frontendStefano Stabellini1-0/+19
Once a request is completed, xen_9pfs_push_and_notify gets called. In xen_9pfs_push_and_notify, update the indexes (data has already been copied to the sg by the common code) and send a notification to the frontend. Schedule the bottom-half to check if we already have any other requests pending. Signed-off-by: Stefano Stabellini <stefano@aporeto.com> CC: anthony.perard@citrix.com CC: jgross@suse.com CC: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> CC: Greg Kurz <groug@kaod.org>
2017-04-25xen/9pfs: implement in/out_iov_from_pdu and vmarshal/vunmarshalStefano Stabellini1-2/+97
Implement xen_9pfs_init_in/out_iov_from_pdu and xen_9pfs_pdu_vmarshal/vunmarshall by creating new sg pointing to the data on the ring. This is safe as we only handle one request per ring at any given time. Signed-off-by: Stefano Stabellini <stefano@aporeto.com> CC: anthony.perard@citrix.com CC: jgross@suse.com CC: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> CC: Greg Kurz <groug@kaod.org>
2017-04-25xen/9pfs: receive requests from the frontendStefano Stabellini1-0/+50
Upon receiving an event channel notification from the frontend, schedule the bottom half. From the bottom half, read one request from the ring, create a pdu and call pdu_submit to handle it. For now, only handle one request per ring at a time. Signed-off-by: Stefano Stabellini <stefano@aporeto.com> CC: anthony.perard@citrix.com CC: jgross@suse.com CC: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> CC: Greg Kurz <groug@kaod.org>
2017-04-25xen/9pfs: connect to the frontendStefano Stabellini1-1/+181
Write the limits of the backend to xenstore. Connect to the frontend. Upon connection, allocate the rings according to the protocol specification. Initialize a QEMUBH to schedule work upon receiving an event channel notification from the frontend. Signed-off-by: Stefano Stabellini <stefano@aporeto.com> CC: anthony.perard@citrix.com CC: jgross@suse.com CC: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> CC: Greg Kurz <groug@kaod.org>
2017-04-25xen/9pfs: introduce Xen 9pfs backendStefano Stabellini2-0/+117
Introduce the Xen 9pfs backend: add struct XenDevOps to register as a Xen backend and add struct V9fsTransport to register as v9fs transport. All functions are empty stubs for now. Signed-off-by: Stefano Stabellini <stefano@aporeto.com> Reviewed-by: Greg Kurz <groug@kaod.org> CC: anthony.perard@citrix.com CC: jgross@suse.com CC: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> CC: Greg Kurz <groug@kaod.org>
2017-04-219p: introduce a type for the 9p headerStefano Stabellini2-5/+7
Use the new type in virtio-9p-device. Signed-off-by: Stefano Stabellini <stefano@aporeto.com> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> CC: anthony.perard@citrix.com CC: jgross@suse.com CC: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> CC: Greg Kurz <groug@kaod.org>
2017-04-189pfs: local: set the path of the export root to "."Greg Kurz1-1/+6
The local backend was recently converted to using "at*()" syscalls in order to ensure all accesses happen below the shared directory. This requires that we only pass relative paths, otherwise the dirfd argument to the "at*()" syscalls is ignored and the path is treated as an absolute path in the host. This is actually the case for paths in all fids, with the notable exception of the root fid, whose path is "/". This causes the following backend ops to act on the "/" directory of the host instead of the virtfs shared directory when the export root is involved: - lstat - chmod - chown - utimensat ie, chmod /9p_mount_point in the guest will be converted to chmod / in the host for example. This could cause security issues with a privileged QEMU. All "*at()" syscalls are being passed an open file descriptor. In the case of the export root, this file descriptor points to the path in the host that was passed to -fsdev. The fix is thus as simple as changing the path of the export root fid to be "." instead of "/". This is CVE-2017-7471. Cc: qemu-stable@nongnu.org Reported-by: Léo Gaspard <leo@gaspard.io> Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-109pfs: xattr: fix memory leak in v9fs_list_xattrLi Qiang1-0/+1
Free 'orig_value' in error path. Signed-off-by: Li Qiang <liqiang6-s@360.cn> Signed-off-by: Greg Kurz <groug@kaod.org>
2017-04-049pfs: clear migration blocker at session resetGreg Kurz1-5/+6
The migration blocker survives a device reset: if the guest mounts a 9p share and then gets rebooted with system_reset, it will be unmigratable until it remounts and umounts the 9p share again. This happens because the migration blocker is supposed to be cleared when we put the last reference on the root fid, but virtfs_reset() wrongly calls free_fid() instead of put_fid(). This patch fixes virtfs_reset() so that it honor the way fids are supposed to be manipulated: first get a reference and later put it back when you're done. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Li Qiang <liqiang6-s@360.cn>
2017-04-049pfs: fix multiple flush for same requestGreg Kurz1-2/+4
If a client tries to flush the same outstanding request several times, only the first flush completes. Subsequent ones keep waiting for the request completion in v9fs_flush() and, therefore, leak a PDU. This will cause QEMU to hang when draining active PDUs the next time the device is reset. Let have each flush request wake up the next one if any. The last waiter frees the cancelled PDU. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com>
2017-03-279pfs: fix file descriptor leakLi Qiang1-0/+8
The v9fs_create() and v9fs_lcreate() functions are used to create a file on the backend and to associate it to a fid. The fid shouldn't be already in-use, otherwise both functions may silently leak a file descriptor or allocated memory. The current code doesn't check that. This patch ensures that the fid isn't already associated to anything before using it. Signed-off-by: Li Qiang <liqiang6-s@360.cn> (reworded the changelog, Greg Kurz) Signed-off-by: Greg Kurz <groug@kaod.org>
2017-03-219pfs: proxy: assert if unmarshal failsGreg Kurz1-11/+11
Replies from the virtfs proxy are made up of a fixed-size header (8 bytes) and a payload of variable size (maximum 64kb). When receiving a reply, the proxy backend first reads the whole header and then unmarshals it. If the header is okay, it then does the same operation with the payload. Since the proxy backend uses a pre-allocated buffer which has enough room for a header and the maximum payload size, marshalling should never fail with fixed size arguments. Any error here is likely to result from a more serious corruption in QEMU and we'd better dump core right away. This patch adds error checks where they are missing and converts the associated error paths into assertions. This should also address Coverity's complaints CID 1348519 and CID 1348520, about not always checking the return value of proxy_unmarshal(). Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2017-03-219pfs: don't try to flush self and avoid QEMU hang on resetGreg Kurz1-4/+8
According to the 9P spec [*], when a client wants to cancel a pending I/O request identified by a given tag (uint16), it must send a Tflush message and wait for the server to respond with a Rflush message before reusing this tag for another I/O. The server may still send a completion message for the I/O if it wasn't actually cancelled but the Rflush message must arrive after that. QEMU hence waits for the flushed PDU to complete before sending the Rflush message back to the client. If a client sends 'Tflush tag oldtag' and tag == oldtag, QEMU will then allocate a PDU identified by tag, find it in the PDU list and wait for this same PDU to complete... i.e. wait for a completion that will never happen. This causes a tag and ring slot leak in the guest, and a PDU leak in QEMU, all of them limited by the maximal number of PDUs (128). But, worse, this causes QEMU to hang on device reset since v9fs_reset() wants to drain all pending I/O. This insane behavior is likely to denote a bug in the client, and it would deserve an Rerror message to be sent back. Unfortunately, the protocol allows it and requires all flush requests to suceed (only a Tflush response is expected). The only option is to detect when we have to handle a self-referencing flush request and report success to the client right away. [*] http://man.cat-v.org/plan_9/5/flush Reported-by: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Greg Kurz <groug@kaod.org>
2017-03-069pfs: fix vulnerability in openat_dir() and local_unlinkat_common()Greg Kurz2-2/+3
We should pass O_NOFOLLOW otherwise openat() will follow symlinks and make QEMU vulnerable. While here, we also fix local_unlinkat_common() to use openat_dir() for the same reasons (it was a leftover in the original patchset actually). This fixes CVE-2016-9602. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Daniel P. Berrange <berrange@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2017-03-069pfs: fix O_PATH build break with older glibc versionsGreg Kurz1-1/+6
When O_PATH is used with O_DIRECTORY, it only acts as an optimization: the openat() syscall simply finds the name in the VFS, and doesn't trigger the underlying filesystem. On systems that don't define O_PATH, because they have glibc version 2.13 or older for example, we can safely omit it. We don't want to deactivate O_PATH globally though, in case it is used without O_DIRECTORY. The is done with a dedicated macro. Systems without O_PATH may thus fail to resolve names that involve unreadable directories, compared to newer systems succeeding, but such corner case failure is our only option on those older systems to avoid the security hole of chasing symlinks inappropriately. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Eric Blake <eblake@redhat.com> (added last paragraph to changelog as suggested by Eric Blake) Signed-off-by: Greg Kurz <groug@kaod.org>
2017-03-069pfs: don't use AT_EMPTY_PATH in local_set_cred_passthrough()Greg Kurz1-1/+1
The name argument can never be an empty string, and dirfd always point to the containing directory of the file name. AT_EMPTY_PATH is hence useless here. Also it breaks build with glibc version 2.13 and older. It is actually an oversight of a previous tentative patch to implement this function. We can safely drop it. Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Greg Kurz <groug@kaod.org> Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Eric Blake <eblake@redhat.com>
2017-03-069pfs: fail local_statfs() earlierGreg Kurz1-0/+3
If we cannot open the given path, we can return right away instead of passing -1 to fstatfs() and close(). This will make Coverity happy. (Coverity issue CID1371729) Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Daniel P. berrange <berrange@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2017-03-069pfs: fix fd leak in local_opendir()Greg Kurz1-0/+1
Coverity issue CID1371731 Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Daniel P. Berrange <berrange@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>