Skip to content

Commit

Permalink
uacce: unmap remaining mmapping from user space
Browse files Browse the repository at this point in the history
When uacce parent device module is removed, user app may
still keep the mmaped area, which can be accessed unsafely.
When rmmod, Parent device driver will call uacce_remove,
which unmap all remaining mapping from user space for safety.
VM_FAULT_SIGBUS is also reported to user space accordingly.

Suggested-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
zhangfeigao authored and herbertx committed Mar 6, 2020
1 parent 732e540 commit acc670d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
16 changes: 16 additions & 0 deletions drivers/misc/uacce/uacce.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ static int uacce_fops_open(struct inode *inode, struct file *filep)

init_waitqueue_head(&q->wait);
filep->private_data = q;
uacce->inode = inode;
q->state = UACCE_Q_INIT;

return 0;
Expand Down Expand Up @@ -253,6 +254,14 @@ static int uacce_fops_release(struct inode *inode, struct file *filep)
return 0;
}

static vm_fault_t uacce_vma_fault(struct vm_fault *vmf)
{
if (vmf->flags & (FAULT_FLAG_MKWRITE | FAULT_FLAG_WRITE))
return VM_FAULT_SIGBUS;

return 0;
}

static void uacce_vma_close(struct vm_area_struct *vma)
{
struct uacce_queue *q = vma->vm_private_data;
Expand All @@ -265,6 +274,7 @@ static void uacce_vma_close(struct vm_area_struct *vma)
}

static const struct vm_operations_struct uacce_vm_ops = {
.fault = uacce_vma_fault,
.close = uacce_vma_close,
};

Expand Down Expand Up @@ -556,6 +566,12 @@ void uacce_remove(struct uacce_device *uacce)

if (!uacce)
return;
/*
* unmap remaining mapping from user space, preventing user still
* access the mmaped area while parent device is already removed
*/
if (uacce->inode)
unmap_mapping_range(uacce->inode->i_mapping, 0, 0, 1);

/* ensure no open queue remains */
mutex_lock(&uacce->mm_lock);
Expand Down
2 changes: 2 additions & 0 deletions include/linux/uacce.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct uacce_queue {
* @priv: private pointer of the uacce
* @mm_list: list head of uacce_mm->list
* @mm_lock: lock for mm_list
* @inode: core vfs
*/
struct uacce_device {
const char *algs;
Expand All @@ -113,6 +114,7 @@ struct uacce_device {
void *priv;
struct list_head mm_list;
struct mutex mm_lock;
struct inode *inode;
};

/**
Expand Down

0 comments on commit acc670d

Please sign in to comment.