--- /dev/null
+From 6a8dadcca81fceff9976e8828cceb072873b7bd5 Mon Sep 17 00:00:00 2001
+From: Todd Poynor <toddpoynor@google.com>
+Date: Tue, 15 Aug 2017 22:41:08 -0700
+Subject: scsi: sg: protect against races between mmap() and SG_SET_RESERVED_SIZE
+
+From: Todd Poynor <toddpoynor@google.com>
+
+commit 6a8dadcca81fceff9976e8828cceb072873b7bd5 upstream.
+
+Take f_mutex around mmap() processing to protect against races with the
+SG_SET_RESERVED_SIZE ioctl. Ensure the reserve buffer length remains
+consistent during the mapping operation, and set the "mmap called" flag
+to prevent further changes to the reserved buffer size as an atomic
+operation with the mapping.
+
+[mkp: fixed whitespace]
+
+Signed-off-by: Todd Poynor <toddpoynor@google.com>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -1233,6 +1233,7 @@ sg_mmap(struct file *filp, struct vm_are
+ unsigned long req_sz, len, sa;
+ Sg_scatter_hold *rsv_schp;
+ int k, length;
++ int ret = 0;
+
+ if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
+ return -ENXIO;
+@@ -1243,8 +1244,11 @@ sg_mmap(struct file *filp, struct vm_are
+ if (vma->vm_pgoff)
+ return -EINVAL; /* want no offset */
+ rsv_schp = &sfp->reserve;
+- if (req_sz > rsv_schp->bufflen)
+- return -ENOMEM; /* cannot map more than reserved buffer */
++ mutex_lock(&sfp->f_mutex);
++ if (req_sz > rsv_schp->bufflen) {
++ ret = -ENOMEM; /* cannot map more than reserved buffer */
++ goto out;
++ }
+
+ sa = vma->vm_start;
+ length = 1 << (PAGE_SHIFT + rsv_schp->page_order);
+@@ -1258,7 +1262,9 @@ sg_mmap(struct file *filp, struct vm_are
+ vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
+ vma->vm_private_data = sfp;
+ vma->vm_ops = &sg_mmap_vm_ops;
+- return 0;
++out:
++ mutex_unlock(&sfp->f_mutex);
++ return ret;
+ }
+
+ static void
--- /dev/null
+From 8d26f491116feaa0b16de370b6a7ba40a40fa0b4 Mon Sep 17 00:00:00 2001
+From: Todd Poynor <toddpoynor@google.com>
+Date: Tue, 15 Aug 2017 21:48:43 -0700
+Subject: scsi: sg: recheck MMAP_IO request length with lock held
+
+From: Todd Poynor <toddpoynor@google.com>
+
+commit 8d26f491116feaa0b16de370b6a7ba40a40fa0b4 upstream.
+
+Commit 1bc0eb044615 ("scsi: sg: protect accesses to 'reserved' page
+array") adds needed concurrency protection for the "reserve" buffer.
+Some checks that are initially made outside the lock are replicated once
+the lock is taken to ensure the checks and resulting decisions are made
+using consistent state.
+
+The check that a request with flag SG_FLAG_MMAP_IO set fits in the
+reserve buffer also needs to be performed again under the lock to ensure
+the reserve buffer length compared against matches the value in effect
+when the request is linked to the reserve buffer. An -ENOMEM should be
+returned in this case, instead of switching over to an indirect buffer
+as for non-MMAP_IO requests.
+
+Signed-off-by: Todd Poynor <toddpoynor@google.com>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -1741,9 +1741,12 @@ sg_start_req(Sg_request *srp, unsigned c
+ !sfp->res_in_use) {
+ sfp->res_in_use = 1;
+ sg_link_reserve(sfp, srp, dxfer_len);
+- } else if ((hp->flags & SG_FLAG_MMAP_IO) && sfp->res_in_use) {
++ } else if (hp->flags & SG_FLAG_MMAP_IO) {
++ res = -EBUSY; /* sfp->res_in_use == 1 */
++ if (dxfer_len > rsv_schp->bufflen)
++ res = -ENOMEM;
+ mutex_unlock(&sfp->f_mutex);
+- return -EBUSY;
++ return res;
+ } else {
+ res = sg_build_indirect(req_schp, sfp, dxfer_len);
+ if (res) {