ANDROID: dma-buf: Don't change vm_ops if vm_file changes

When CONFIG_DMABUF_SYSFS_STATS=y, dma_buf_do_mmap() will call a
dma-bufs mmap() callback before overriding the open() and close()
callbacks for the dma-buf's vm_operations_stuct, such that
dma_buf_vma_open() and dma_buf_vma_close() are used instead. Each of
the two aforementioend callbacks assumes that the vma->vm_file pointer
they use points to a dma-buf file.

However, it is possible that during the invocation of the dma-buf's
mmap() callback, that the vma->vm_file pointer changes to store
something other than a dma-buf file (it is permissible to do this so
long as certain conditions are met, see the callsite of call_mmap in
mm/mmap.c as of commit a2e00b4b5d ("FROMGIT: mm/slub: add taint
after the errors are printed"). This means that when
dma_buf_vma_open() and dma_buf_vma_close() run, that their accesses to
vma->vm_file will cease to be semantically valid.

Accordingly, only override the open() and close() vm_operations_struct
callbacks if a dma-buf's mmap() callback preserves the vma->vm_file
across the mmap() callback.

Bug: 191742286
Fixes: 9132fbe545 ("ANDROID: dmabuf: Add mmap_count to struct dmabuf")
Signed-off-by: Chris Goldsworthy <quic_cgoldswo@quicinc.com>
Change-Id: I4f80ade7f0bc85e2cb9219478550dcb6bbb29f3e
This commit is contained in:
Chris Goldsworthy
2021-06-22 14:23:06 -07:00
parent a2e00b4b5d
commit fca37c251a

View File

@@ -173,12 +173,17 @@ static void dma_buf_vma_close(struct vm_area_struct *vma)
static int dma_buf_do_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
{
/* call this first because the exporter might override vma->vm_ops */
int ret = dmabuf->ops->mmap(dmabuf, vma);
int ret;
struct file *orig_vm_file = vma->vm_file;
/* call this first because the exporter might override vma->vm_ops */
ret = dmabuf->ops->mmap(dmabuf, vma);
if (ret)
return ret;
if (orig_vm_file != vma->vm_file)
return 0;
/* save the exporter provided vm_ops */
dmabuf->exp_vm_ops = vma->vm_ops;
dmabuf->vm_ops = *(dmabuf->exp_vm_ops);