[pve-devel] [PATCH kvm] various CVE fixes
Wolfgang Bumiller
w.bumiller at proxmox.com
Wed Sep 7 11:58:00 CEST 2016
CVE-2016-7116:
9pfs: forbid illegal path names
9pfs: forbid . and .. in file names
9pfs: handle walk of ".." in the root directory
CVE-2016-7155: scsi: check page count while initialising descriptor rings
CVE-2016-7156: scsi: pvscsi: avoid infinite loop while building SG list
CVE-2016-7157: scsi: mptconfig: fix an assert expression
---
.../0001-9pfs-forbid-illegal-path-names.patch | 178 +++++++++++++++++++++
.../0002-9pfs-forbid-.-and-.-in-file-names.patch | 159 ++++++++++++++++++
...fs-handle-walk-of-.-in-the-root-directory.patch | 126 +++++++++++++++
...page-count-while-initialising-descriptor-.patch | 83 ++++++++++
...-avoid-infinite-loop-while-building-SG-li.patch | 63 ++++++++
...7-scsi-mptconfig-fix-an-assert-expression.patch | 35 ++++
debian/patches/series | 6 +
7 files changed, 650 insertions(+)
create mode 100644 debian/patches/extra/0001-9pfs-forbid-illegal-path-names.patch
create mode 100644 debian/patches/extra/0002-9pfs-forbid-.-and-.-in-file-names.patch
create mode 100644 debian/patches/extra/0003-9pfs-handle-walk-of-.-in-the-root-directory.patch
create mode 100644 debian/patches/extra/CVE-2016-7155-scsi-check-page-count-while-initialising-descriptor-.patch
create mode 100644 debian/patches/extra/CVE-2016-7156-scsi-pvscsi-avoid-infinite-loop-while-building-SG-li.patch
create mode 100644 debian/patches/extra/CVE-2016-7157-scsi-mptconfig-fix-an-assert-expression.patch
diff --git a/debian/patches/extra/0001-9pfs-forbid-illegal-path-names.patch b/debian/patches/extra/0001-9pfs-forbid-illegal-path-names.patch
new file mode 100644
index 0000000..15d3119
--- /dev/null
+++ b/debian/patches/extra/0001-9pfs-forbid-illegal-path-names.patch
@@ -0,0 +1,178 @@
+From 21289fc663198d96ae2ca145a425f2e21ed4637a Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug at kaod.org>
+Date: Tue, 30 Aug 2016 19:11:05 +0200
+Subject: [PATCH 1/6] 9pfs: forbid illegal path names
+
+Empty path components don't make sense for most commands and may cause
+undefined behavior, depending on the backend.
+
+Also, the walk request described in the 9P spec [1] clearly shows that
+the client is supposed to send individual path components: the official
+linux client never sends portions of path containing the / character for
+example.
+
+Moreover, the 9P spec [2] also states that a system can decide to restrict
+the set of supported characters used in path components, with an explicit
+mention "to remove slashes from name components".
+
+This patch introduces a new name_is_illegal() helper that checks the
+names sent by the client are not empty and don't contain unwanted chars.
+Since 9pfs is only supported on linux hosts, only the / character is
+checked at the moment. When support for other hosts (AKA. win32) is added,
+other chars may need to be blacklisted as well.
+
+If a client sends an illegal path component, the request will fail and
+ENOENT is returned to the client.
+
+[1] http://man.cat-v.org/plan_9/5/walk
+[2] http://man.cat-v.org/plan_9/5/intro
+
+Suggested-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Greg Kurz <groug at kaod.org>
+Reviewed-by: Eric Blake <eblake at redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
+---
+ hw/9pfs/9p.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
+index f5e3012..53c466b 100644
+--- a/hw/9pfs/9p.c
++++ b/hw/9pfs/9p.c
+@@ -1254,6 +1254,11 @@ static int v9fs_walk_marshal(V9fsPDU *pdu, uint16_t nwnames, V9fsQID *qids)
+ return offset;
+ }
+
++static bool name_is_illegal(const char *name)
++{
++ return !*name || strchr(name, '/') != NULL;
++}
++
+ static void v9fs_walk(void *opaque)
+ {
+ int name_idx;
+@@ -1287,6 +1292,10 @@ static void v9fs_walk(void *opaque)
+ if (err < 0) {
+ goto out_nofid;
+ }
++ if (name_is_illegal(wnames[i].data)) {
++ err = -ENOENT;
++ goto out_nofid;
++ }
+ offset += err;
+ }
+ } else if (nwnames > P9_MAXWELEM) {
+@@ -1481,6 +1490,11 @@ static void v9fs_lcreate(void *opaque)
+ }
+ trace_v9fs_lcreate(pdu->tag, pdu->id, dfid, flags, mode, gid);
+
++ if (name_is_illegal(name.data)) {
++ err = -ENOENT;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, dfid);
+ if (fidp == NULL) {
+ err = -ENOENT;
+@@ -2066,6 +2080,11 @@ static void v9fs_create(void *opaque)
+ }
+ trace_v9fs_create(pdu->tag, pdu->id, fid, name.data, perm, mode);
+
++ if (name_is_illegal(name.data)) {
++ err = -ENOENT;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, fid);
+ if (fidp == NULL) {
+ err = -EINVAL;
+@@ -2231,6 +2250,11 @@ static void v9fs_symlink(void *opaque)
+ }
+ trace_v9fs_symlink(pdu->tag, pdu->id, dfid, name.data, symname.data, gid);
+
++ if (name_is_illegal(name.data)) {
++ err = -ENOENT;
++ goto out_nofid;
++ }
++
+ dfidp = get_fid(pdu, dfid);
+ if (dfidp == NULL) {
+ err = -EINVAL;
+@@ -2305,6 +2329,11 @@ static void v9fs_link(void *opaque)
+ }
+ trace_v9fs_link(pdu->tag, pdu->id, dfid, oldfid, name.data);
+
++ if (name_is_illegal(name.data)) {
++ err = -ENOENT;
++ goto out_nofid;
++ }
++
+ dfidp = get_fid(pdu, dfid);
+ if (dfidp == NULL) {
+ err = -ENOENT;
+@@ -2387,6 +2416,12 @@ static void v9fs_unlinkat(void *opaque)
+ if (err < 0) {
+ goto out_nofid;
+ }
++
++ if (name_is_illegal(name.data)) {
++ err = -ENOENT;
++ goto out_nofid;
++ }
++
+ dfidp = get_fid(pdu, dfid);
+ if (dfidp == NULL) {
+ err = -EINVAL;
+@@ -2493,6 +2528,12 @@ static void v9fs_rename(void *opaque)
+ if (err < 0) {
+ goto out_nofid;
+ }
++
++ if (name_is_illegal(name.data)) {
++ err = -ENOENT;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, fid);
+ if (fidp == NULL) {
+ err = -ENOENT;
+@@ -2605,6 +2646,11 @@ static void v9fs_renameat(void *opaque)
+ goto out_err;
+ }
+
++ if (name_is_illegal(old_name.data) || name_is_illegal(new_name.data)) {
++ err = -ENOENT;
++ goto out_err;
++ }
++
+ v9fs_path_write_lock(s);
+ err = v9fs_complete_renameat(pdu, olddirfid,
+ &old_name, newdirfid, &new_name);
+@@ -2815,6 +2861,11 @@ static void v9fs_mknod(void *opaque)
+ }
+ trace_v9fs_mknod(pdu->tag, pdu->id, fid, mode, major, minor);
+
++ if (name_is_illegal(name.data)) {
++ err = -ENOENT;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, fid);
+ if (fidp == NULL) {
+ err = -ENOENT;
+@@ -2966,6 +3017,11 @@ static void v9fs_mkdir(void *opaque)
+ }
+ trace_v9fs_mkdir(pdu->tag, pdu->id, fid, name.data, mode, gid);
+
++ if (name_is_illegal(name.data)) {
++ err = -ENOENT;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, fid);
+ if (fidp == NULL) {
+ err = -ENOENT;
+--
+2.1.4
+
diff --git a/debian/patches/extra/0002-9pfs-forbid-.-and-.-in-file-names.patch b/debian/patches/extra/0002-9pfs-forbid-.-and-.-in-file-names.patch
new file mode 100644
index 0000000..c2c0500
--- /dev/null
+++ b/debian/patches/extra/0002-9pfs-forbid-.-and-.-in-file-names.patch
@@ -0,0 +1,159 @@
+From 3ae00feb459657766ec623de7eae8f014a660ab4 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug at kaod.org>
+Date: Tue, 30 Aug 2016 19:13:11 +0200
+Subject: [PATCH 2/6] 9pfs: forbid . and .. in file names
+
+According to the 9P spec http://man.cat-v.org/plan_9/5/open about the
+create request:
+
+The names . and .. are special; it is illegal to create files with these
+names.
+
+This patch causes the create and lcreate requests to fail with EINVAL if
+the file name is either "." or "..".
+
+Even if it isn't explicitly written in the spec, this patch extends the
+checking to all requests that may cause a directory entry to be created:
+
+ - mknod
+ - rename
+ - renameat
+ - mkdir
+ - link
+ - symlink
+
+The unlinkat request also gets patched for consistency (even if
+rmdir("foo/..") is expected to fail according to POSIX.1-2001).
+
+The various error values come from the linux manual pages.
+
+Suggested-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Greg Kurz <groug at kaod.org>
+Reviewed-by: Eric Blake <eblake at redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
+---
+ hw/9pfs/9p.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 51 insertions(+)
+
+diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
+index 53c466b..1e96427 100644
+--- a/hw/9pfs/9p.c
++++ b/hw/9pfs/9p.c
+@@ -1495,6 +1495,11 @@ static void v9fs_lcreate(void *opaque)
+ goto out_nofid;
+ }
+
++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
++ err = -EEXIST;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, dfid);
+ if (fidp == NULL) {
+ err = -ENOENT;
+@@ -2085,6 +2090,11 @@ static void v9fs_create(void *opaque)
+ goto out_nofid;
+ }
+
++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
++ err = -EEXIST;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, fid);
+ if (fidp == NULL) {
+ err = -EINVAL;
+@@ -2255,6 +2265,11 @@ static void v9fs_symlink(void *opaque)
+ goto out_nofid;
+ }
+
++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
++ err = -EEXIST;
++ goto out_nofid;
++ }
++
+ dfidp = get_fid(pdu, dfid);
+ if (dfidp == NULL) {
+ err = -EINVAL;
+@@ -2334,6 +2349,11 @@ static void v9fs_link(void *opaque)
+ goto out_nofid;
+ }
+
++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
++ err = -EEXIST;
++ goto out_nofid;
++ }
++
+ dfidp = get_fid(pdu, dfid);
+ if (dfidp == NULL) {
+ err = -ENOENT;
+@@ -2422,6 +2442,16 @@ static void v9fs_unlinkat(void *opaque)
+ goto out_nofid;
+ }
+
++ if (!strcmp(".", name.data)) {
++ err = -EINVAL;
++ goto out_nofid;
++ }
++
++ if (!strcmp("..", name.data)) {
++ err = -ENOTEMPTY;
++ goto out_nofid;
++ }
++
+ dfidp = get_fid(pdu, dfid);
+ if (dfidp == NULL) {
+ err = -EINVAL;
+@@ -2534,6 +2564,11 @@ static void v9fs_rename(void *opaque)
+ goto out_nofid;
+ }
+
++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
++ err = -EISDIR;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, fid);
+ if (fidp == NULL) {
+ err = -ENOENT;
+@@ -2651,6 +2686,12 @@ static void v9fs_renameat(void *opaque)
+ goto out_err;
+ }
+
++ if (!strcmp(".", old_name.data) || !strcmp("..", old_name.data) ||
++ !strcmp(".", new_name.data) || !strcmp("..", new_name.data)) {
++ err = -EISDIR;
++ goto out_err;
++ }
++
+ v9fs_path_write_lock(s);
+ err = v9fs_complete_renameat(pdu, olddirfid,
+ &old_name, newdirfid, &new_name);
+@@ -2866,6 +2907,11 @@ static void v9fs_mknod(void *opaque)
+ goto out_nofid;
+ }
+
++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
++ err = -EEXIST;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, fid);
+ if (fidp == NULL) {
+ err = -ENOENT;
+@@ -3022,6 +3068,11 @@ static void v9fs_mkdir(void *opaque)
+ goto out_nofid;
+ }
+
++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) {
++ err = -EEXIST;
++ goto out_nofid;
++ }
++
+ fidp = get_fid(pdu, fid);
+ if (fidp == NULL) {
+ err = -ENOENT;
+--
+2.1.4
+
diff --git a/debian/patches/extra/0003-9pfs-handle-walk-of-.-in-the-root-directory.patch b/debian/patches/extra/0003-9pfs-handle-walk-of-.-in-the-root-directory.patch
new file mode 100644
index 0000000..d4f22c2
--- /dev/null
+++ b/debian/patches/extra/0003-9pfs-handle-walk-of-.-in-the-root-directory.patch
@@ -0,0 +1,126 @@
+From 348503ea115b336343166b87271208ffc0bdeb0a Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug at kaod.org>
+Date: Tue, 30 Aug 2016 17:02:27 +0200
+Subject: [PATCH 3/6] 9pfs: handle walk of ".." in the root directory
+
+The 9P spec at http://man.cat-v.org/plan_9/5/intro says:
+
+All directories must support walks to the directory .. (dot-dot) meaning
+parent directory, although by convention directories contain no explicit
+entry for .. or . (dot). The parent of the root directory of a server's
+tree is itself.
+
+This means that a client cannot walk further than the root directory
+exported by the server. In other words, if the client wants to walk
+"/.." or "/foo/../..", the server should answer like the request was
+to walk "/".
+
+This patch just does that:
+- we cache the QID of the root directory at attach time
+- during the walk we compare the QID of each path component with the root
+ QID to detect if we're in a "/.." situation
+- if so, we skip the current component and go to the next one
+
+Signed-off-by: Greg Kurz <groug at kaod.org>
+Reviewed-by: Eric Blake <eblake at redhat.com>
+Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
+---
+ hw/9pfs/9p.c | 40 +++++++++++++++++++++++++++++++---------
+ hw/9pfs/9p.h | 1 +
+ 2 files changed, 32 insertions(+), 9 deletions(-)
+
+diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
+index 1e96427..1ac05b2 100644
+--- a/hw/9pfs/9p.c
++++ b/hw/9pfs/9p.c
+@@ -1008,6 +1008,7 @@ static void v9fs_attach(void *opaque)
+ goto out;
+ }
+ err += offset;
++ memcpy(&s->root_qid, &qid, sizeof(qid));
+ trace_v9fs_attach_return(pdu->tag, pdu->id,
+ qid.type, qid.version, qid.path);
+ /*
+@@ -1259,6 +1260,14 @@ static bool name_is_illegal(const char *name)
+ return !*name || strchr(name, '/') != NULL;
+ }
+
++static bool not_same_qid(const V9fsQID *qid1, const V9fsQID *qid2)
++{
++ return
++ qid1->type != qid2->type ||
++ qid1->version != qid2->version ||
++ qid1->path != qid2->path;
++}
++
+ static void v9fs_walk(void *opaque)
+ {
+ int name_idx;
+@@ -1274,6 +1283,7 @@ static void v9fs_walk(void *opaque)
+ V9fsFidState *newfidp = NULL;
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
++ V9fsQID qid;
+
+ err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames);
+ if (err < 0) {
+@@ -1307,6 +1317,12 @@ static void v9fs_walk(void *opaque)
+ err = -ENOENT;
+ goto out_nofid;
+ }
++
++ err = fid_to_qid(pdu, fidp, &qid);
++ if (err < 0) {
++ goto out;
++ }
++
+ v9fs_path_init(&dpath);
+ v9fs_path_init(&path);
+ /*
+@@ -1316,16 +1332,22 @@ static void v9fs_walk(void *opaque)
+ v9fs_path_copy(&dpath, &fidp->path);
+ v9fs_path_copy(&path, &fidp->path);
+ for (name_idx = 0; name_idx < nwnames; name_idx++) {
+- err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, &path);
+- if (err < 0) {
+- goto out;
+- }
+- err = v9fs_co_lstat(pdu, &path, &stbuf);
+- if (err < 0) {
+- goto out;
++ if (not_same_qid(&pdu->s->root_qid, &qid) ||
++ strcmp("..", wnames[name_idx].data)) {
++ err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data,
++ &path);
++ if (err < 0) {
++ goto out;
++ }
++
++ err = v9fs_co_lstat(pdu, &path, &stbuf);
++ if (err < 0) {
++ goto out;
++ }
++ stat_to_qid(&stbuf, &qid);
++ v9fs_path_copy(&dpath, &path);
+ }
+- stat_to_qid(&stbuf, &qids[name_idx]);
+- v9fs_path_copy(&dpath, &path);
++ memcpy(&qids[name_idx], &qid, sizeof(qid));
+ }
+ if (fid == newfid) {
+ BUG_ON(fidp->fid_type != P9_FID_NONE);
+diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
+index 1a19418..589b3a5 100644
+--- a/hw/9pfs/9p.h
++++ b/hw/9pfs/9p.h
+@@ -219,6 +219,7 @@ typedef struct V9fsState
+ int32_t root_fid;
+ Error *migration_blocker;
+ V9fsConf fsconf;
++ V9fsQID root_qid;
+ } V9fsState;
+
+ /* 9p2000.L open flags */
+--
+2.1.4
+
diff --git a/debian/patches/extra/CVE-2016-7155-scsi-check-page-count-while-initialising-descriptor-.patch b/debian/patches/extra/CVE-2016-7155-scsi-check-page-count-while-initialising-descriptor-.patch
new file mode 100644
index 0000000..54df061
--- /dev/null
+++ b/debian/patches/extra/CVE-2016-7155-scsi-check-page-count-while-initialising-descriptor-.patch
@@ -0,0 +1,83 @@
+From 7c7e45d2bd1a77fbe89dff83fabf89a46479111f Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp at fedoraproject.org>
+Date: Thu, 1 Sep 2016 16:30:51 +0530
+Subject: [PATCH 4/6] scsi: check page count while initialising descriptor
+ rings
+
+Vmware Paravirtual SCSI emulation uses command descriptors to
+process SCSI commands. These descriptors come with their ring
+buffers. A guest could set the page count for these rings to
+an arbitrary value, leading to infinite loop or OOB access.
+Add check to avoid it.
+
+Reported-by: Tom Victor <vv474172261 at gmail.com>
+Reported-by: Li Qiang <liqiang6-s at 360.cn>
+Signed-off-by: Prasad J Pandit <pjp at fedoraproject.org>
+---
+ hw/scsi/vmw_pvscsi.c | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
+index 2d7528d..22f872c 100644
+--- a/hw/scsi/vmw_pvscsi.c
++++ b/hw/scsi/vmw_pvscsi.c
+@@ -153,7 +153,7 @@ pvscsi_log2(uint32_t input)
+ return log;
+ }
+
+-static int
++static void
+ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
+ {
+ int i;
+@@ -161,10 +161,6 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
+ uint32_t req_ring_size, cmp_ring_size;
+ m->rs_pa = ri->ringsStatePPN << VMW_PAGE_SHIFT;
+
+- if ((ri->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)
+- || (ri->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)) {
+- return -1;
+- }
+ req_ring_size = ri->reqRingNumPages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
+ cmp_ring_size = ri->cmpRingNumPages * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE;
+ txr_len_log2 = pvscsi_log2(req_ring_size - 1);
+@@ -196,8 +192,6 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
+
+ /* Flush ring state page changes */
+ smp_wmb();
+-
+- return 0;
+ }
+
+ static int
+@@ -747,7 +741,7 @@ pvscsi_dbg_dump_tx_rings_config(PVSCSICmdDescSetupRings *rc)
+
+ trace_pvscsi_tx_rings_num_pages("Confirm Ring", rc->cmpRingNumPages);
+ for (i = 0; i < rc->cmpRingNumPages; i++) {
+- trace_pvscsi_tx_rings_ppn("Confirm Ring", rc->reqRingPPNs[i]);
++ trace_pvscsi_tx_rings_ppn("Confirm Ring", rc->cmpRingPPNs[i]);
+ }
+ }
+
+@@ -780,11 +774,16 @@ pvscsi_on_cmd_setup_rings(PVSCSIState *s)
+
+ trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_RINGS");
+
+- pvscsi_dbg_dump_tx_rings_config(rc);
+- if (pvscsi_ring_init_data(&s->rings, rc) < 0) {
++ if (!rc->reqRingNumPages
++ || rc->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
++ || !rc->cmpRingNumPages
++ || rc->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES) {
+ return PVSCSI_COMMAND_PROCESSING_FAILED;
+ }
+
++ pvscsi_dbg_dump_tx_rings_config(rc);
++ pvscsi_ring_init_data(&s->rings, rc);
++
+ s->rings_info_valid = TRUE;
+ return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
+ }
+--
+2.1.4
+
diff --git a/debian/patches/extra/CVE-2016-7156-scsi-pvscsi-avoid-infinite-loop-while-building-SG-li.patch b/debian/patches/extra/CVE-2016-7156-scsi-pvscsi-avoid-infinite-loop-while-building-SG-li.patch
new file mode 100644
index 0000000..d4a133a
--- /dev/null
+++ b/debian/patches/extra/CVE-2016-7156-scsi-pvscsi-avoid-infinite-loop-while-building-SG-li.patch
@@ -0,0 +1,63 @@
+From a8ceb006190b9072b0b9866ec5a07bd6de4eca6d Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp at fedoraproject.org>
+Date: Tue, 6 Sep 2016 23:23:17 +0530
+Subject: [PATCH 5/6] scsi: pvscsi: avoid infinite loop while building SG list
+
+In PVSCSI paravirtual SCSI bus, pvscsi_convert_sglist can take a very
+long time or go into an infinite loop due to two different bugs:
+
+1) the request descriptor data length is defined to be 64 bit. While
+building SG list from a request descriptor, it gets truncated to 32bit
+in routine 'pvscsi_convert_sglist'. This could lead to an infinite loop
+situation for large 'dataLen' values, when data_length is cast to uint32_t
+and chunk_size becomes always zero. Fix this by removing the incorrect
+cast.
+
+2) pvscsi_get_next_sg_elem can be called arbitrarily many times if the
+element has a zero length. Get out of the loop early when this happens,
+by introducing an upper limit on the number of SG list elements.
+
+Reported-by: Li Qiang <liqiang6-s at 360.cn>
+Signed-off-by: Prasad J Pandit <pjp at fedoraproject.org>
+---
+ hw/scsi/vmw_pvscsi.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
+index 22f872c..e43e0a4 100644
+--- a/hw/scsi/vmw_pvscsi.c
++++ b/hw/scsi/vmw_pvscsi.c
+@@ -40,6 +40,8 @@
+ #define PVSCSI_MAX_DEVS (64)
+ #define PVSCSI_MSIX_NUM_VECTORS (1)
+
++#define PVSCSI_MAX_SG_ELEM 2048
++
+ #define PVSCSI_MAX_CMD_DATA_WORDS \
+ (sizeof(PVSCSICmdDescSetupRings)/sizeof(uint32_t))
+
+@@ -629,17 +631,16 @@ pvscsi_queue_pending_descriptor(PVSCSIState *s, SCSIDevice **d,
+ static void
+ pvscsi_convert_sglist(PVSCSIRequest *r)
+ {
+- int chunk_size;
++ uint32_t chunk_size, elmcnt = 0;
+ uint64_t data_length = r->req.dataLen;
+ PVSCSISGState sg = r->sg;
+- while (data_length) {
+- while (!sg.resid) {
++ while (data_length && elmcnt < PVSCSI_MAX_SG_ELEM) {
++ while (!sg.resid && elmcnt++ < PVSCSI_MAX_SG_ELEM) {
+ pvscsi_get_next_sg_elem(&sg);
+ trace_pvscsi_convert_sglist(r->req.context, r->sg.dataAddr,
+ r->sg.resid);
+ }
+- assert(data_length > 0);
+- chunk_size = MIN((unsigned) data_length, sg.resid);
++ chunk_size = MIN(data_length, sg.resid);
+ if (chunk_size) {
+ qemu_sglist_add(&r->sgl, sg.dataAddr, chunk_size);
+ }
+--
+2.1.4
+
diff --git a/debian/patches/extra/CVE-2016-7157-scsi-mptconfig-fix-an-assert-expression.patch b/debian/patches/extra/CVE-2016-7157-scsi-mptconfig-fix-an-assert-expression.patch
new file mode 100644
index 0000000..f74c99b
--- /dev/null
+++ b/debian/patches/extra/CVE-2016-7157-scsi-mptconfig-fix-an-assert-expression.patch
@@ -0,0 +1,35 @@
+From a0e2a28c08472ad3468c2f75d20fe1ca02ef8c0b Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp at fedoraproject.org>
+Date: Wed, 31 Aug 2016 17:36:07 +0530
+Subject: [PATCH 6/6] scsi: mptconfig: fix an assert expression
+
+When LSI SAS1068 Host Bus emulator builds configuration page
+headers, mptsas_config_pack() should assert that the size
+fits in a byte. However, the size is expressed in 32-bit
+units, so up to 1020 bytes fit. The assertion was only
+allowing replies up to 252 bytes, so fix it.
+
+Suggested-by: Paolo Bonzini <pbonzini at redhat.com>
+Signed-off-by: Prasad J Pandit <pjp at fedoraproject.org>
+Message-Id: <1472645167-30765-2-git-send-email-ppandit at redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+---
+ hw/scsi/mptconfig.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/scsi/mptconfig.c b/hw/scsi/mptconfig.c
+index 7071854..3e4f400 100644
+--- a/hw/scsi/mptconfig.c
++++ b/hw/scsi/mptconfig.c
+@@ -158,7 +158,7 @@ static size_t mptsas_config_pack(uint8_t **data, const char *fmt, ...)
+ va_end(ap);
+
+ if (data) {
+- assert(ret < 256 && (ret % 4) == 0);
++ assert(ret / 4 < 256 && (ret % 4) == 0);
+ stb_p(*data + 1, ret / 4);
+ }
+ return ret;
+--
+2.1.4
+
diff --git a/debian/patches/series b/debian/patches/series
index 972f109..5ad7435 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -67,3 +67,9 @@ extra/0007-virtio-decrement-vq-inuse-in-virtqueue_discard.patch
extra/0008-iscsi-pass-SCSI-status-back-for-SG_IO.patch
extra/0009-net-limit-allocation-in-nc_sendv_compat.patch
extra/0010-ui-fix-refresh-of-VNC-server-surface.patch
+extra/0001-9pfs-forbid-illegal-path-names.patch
+extra/0002-9pfs-forbid-.-and-.-in-file-names.patch
+extra/0003-9pfs-handle-walk-of-.-in-the-root-directory.patch
+extra/CVE-2016-7155-scsi-check-page-count-while-initialising-descriptor-.patch
+extra/CVE-2016-7156-scsi-pvscsi-avoid-infinite-loop-while-building-SG-li.patch
+extra/CVE-2016-7157-scsi-mptconfig-fix-an-assert-expression.patch
--
2.1.4
More information about the pve-devel
mailing list