From d63fb193e71644a073b77ff5ac6f1216f2f6cf6e Mon Sep 17 00:00:00 2001 From: Li Qiang <liq3ea@gmail.com> Date: Mon, 27 Mar 2017 21:13:19 +0200 Subject: [PATCH 1/2] 9pfs: fix file descriptor leak 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> --- hw/9pfs/9p.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index b8c0b99358..48babce836 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -1550,6 +1550,10 @@ static void coroutine_fn v9fs_lcreate(void *opaque) err = -ENOENT; goto out_nofid; } + if (fidp->fid_type != P9_FID_NONE) { + err = -EINVAL; + goto out; + } flags = get_dotl_openflags(pdu->s, flags); err = v9fs_co_open2(pdu, fidp, &name, gid, @@ -2153,6 +2157,10 @@ static void coroutine_fn v9fs_create(void *opaque) err = -EINVAL; goto out_nofid; } + if (fidp->fid_type != P9_FID_NONE) { + err = -EINVAL; + goto out; + } if (perm & P9_STAT_MODE_DIR) { err = v9fs_co_mkdir(pdu, fidp, &name, perm & 0777, fidp->uid, -1, &stbuf); From 34ef723ce34aaa14f94530c06a0ab3170a19bb59 Mon Sep 17 00:00:00 2001 From: Peter Maydell <peter.maydell@linaro.org> Date: Mon, 27 Mar 2017 18:59:04 +0100 Subject: [PATCH 2/2] tests/virtio-9p-test: Don't call le*_to_cpus on fields of packed struct For a packed struct like 'P9Hdr' the fields within it may not be aligned as much as the natural alignment for their types. This means it is not valid to pass the address of such a field to a function like le32_to_cpus() which operate on uint32_t* and assume alignment. Doing this results in a SIGBUS on hosts like SPARC which have strict alignment requirements. Use ldl_le_p() instead, which is specified to correctly handle unaligned pointers. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Greg Kurz <groug@kaod.org> Signed-off-by: Greg Kurz <groug@kaod.org> --- tests/virtio-9p-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c index 43a1ad813f..ad33d96387 100644 --- a/tests/virtio-9p-test.c +++ b/tests/virtio-9p-test.c @@ -256,8 +256,8 @@ static void v9fs_req_recv(P9Req *req, uint8_t id) qvirtio_wait_queue_isr(v9p->dev, v9p->vq, 1000 * 1000); v9fs_memread(req, &hdr, 7); - le32_to_cpus(&hdr.size); - le16_to_cpus(&hdr.tag); + hdr.size = ldl_le_p(&hdr.size); + hdr.tag = lduw_le_p(&hdr.tag); if (hdr.size >= 7) { break; }