提交 6a8dadcc 编写于 作者: T Todd Poynor 提交者: Martin K. Petersen

scsi: sg: protect against races between mmap() and SG_SET_RESERVED_SIZE

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: NTodd Poynor <toddpoynor@google.com>
Acked-by: NDouglas Gilbert <dgilbert@interlog.com>
Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
上级 8d26f491
...@@ -1262,6 +1262,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -1262,6 +1262,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
unsigned long req_sz, len, sa; unsigned long req_sz, len, sa;
Sg_scatter_hold *rsv_schp; Sg_scatter_hold *rsv_schp;
int k, length; int k, length;
int ret = 0;
if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data))) if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
return -ENXIO; return -ENXIO;
...@@ -1272,8 +1273,11 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -1272,8 +1273,11 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
if (vma->vm_pgoff) if (vma->vm_pgoff)
return -EINVAL; /* want no offset */ return -EINVAL; /* want no offset */
rsv_schp = &sfp->reserve; rsv_schp = &sfp->reserve;
if (req_sz > rsv_schp->bufflen) mutex_lock(&sfp->f_mutex);
return -ENOMEM; /* cannot map more than reserved buffer */ if (req_sz > rsv_schp->bufflen) {
ret = -ENOMEM; /* cannot map more than reserved buffer */
goto out;
}
sa = vma->vm_start; sa = vma->vm_start;
length = 1 << (PAGE_SHIFT + rsv_schp->page_order); length = 1 << (PAGE_SHIFT + rsv_schp->page_order);
...@@ -1287,7 +1291,9 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -1287,7 +1291,9 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = sfp; vma->vm_private_data = sfp;
vma->vm_ops = &sg_mmap_vm_ops; vma->vm_ops = &sg_mmap_vm_ops;
return 0; out:
mutex_unlock(&sfp->f_mutex);
return ret;
} }
static void static void
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
新手
引导
客服 返回
顶部