summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>2019-12-10 18:57:13 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2020-01-05 03:23:08 -0800
commite71cedcb6fd7478c2457cfac73afbd579c8754ad (patch)
treed32c8f5067298042e52205ce7cba176de1328678
parentc9056c1c817129a58c7961758302e75af280cd2f (diff)
downloaddata-kernel-e71cedcb6fd7478c2457cfac73afbd579c8754ad.tar.gz
drivers: shs: protect mmap file operations using shs ep lock
This adds synchronization for the mmap file operation so that an mmap will only occur after a succesful open and will not occur after a release. This is done by using a fault handler for each shared memory file and checking the respective global variable inside of the ep lock. Change-Id: I955dfc8e745b1e275328721e9934ef8c020d8fa3 Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
-rw-r--r--drivers/rmnet/shs/rmnet_shs_wq_mem.c122
1 files changed, 106 insertions, 16 deletions
diff --git a/drivers/rmnet/shs/rmnet_shs_wq_mem.c b/drivers/rmnet/shs/rmnet_shs_wq_mem.c
index 1675517..33abf80 100644
--- a/drivers/rmnet/shs/rmnet_shs_wq_mem.c
+++ b/drivers/rmnet/shs/rmnet_shs_wq_mem.c
@@ -44,32 +44,122 @@ static void rmnet_shs_vm_close(struct vm_area_struct *vma)
return;
}
-static int rmnet_shs_vm_fault(struct vm_fault *vmf)
+static int rmnet_shs_vm_fault_caps(struct vm_fault *vmf)
{
struct page *page = NULL;
struct rmnet_shs_mmap_info *info;
rmnet_shs_wq_ep_lock_bh();
- info = (struct rmnet_shs_mmap_info *) vmf->vma->vm_private_data;
- if (info->data) {
- page = virt_to_page(info->data);
- get_page(page);
- vmf->page = page;
+ if (cap_shared) {
+ info = (struct rmnet_shs_mmap_info *) vmf->vma->vm_private_data;
+ if (info->data) {
+ page = virt_to_page(info->data);
+ get_page(page);
+ vmf->page = page;
+ } else {
+ rmnet_shs_wq_ep_unlock_bh();
+ return VM_FAULT_SIGSEGV;
+ }
+ } else {
+ rmnet_shs_wq_ep_unlock_bh();
+ return VM_FAULT_SIGSEGV;
+ }
+ rmnet_shs_wq_ep_unlock_bh();
+
+ return 0;
+}
+
+
+static int rmnet_shs_vm_fault_g_flows(struct vm_fault *vmf)
+{
+ struct page *page = NULL;
+ struct rmnet_shs_mmap_info *info;
+
+ rmnet_shs_wq_ep_lock_bh();
+ if (gflow_shared) {
+ info = (struct rmnet_shs_mmap_info *) vmf->vma->vm_private_data;
+ if (info->data) {
+ page = virt_to_page(info->data);
+ get_page(page);
+ vmf->page = page;
+ } else {
+ rmnet_shs_wq_ep_unlock_bh();
+ return VM_FAULT_SIGSEGV;
+ }
+ } else {
+ rmnet_shs_wq_ep_unlock_bh();
+ return VM_FAULT_SIGSEGV;
+
+ }
+ rmnet_shs_wq_ep_unlock_bh();
+
+ return 0;
+}
+
+static int rmnet_shs_vm_fault_ss_flows(struct vm_fault *vmf)
+{
+ struct page *page = NULL;
+ struct rmnet_shs_mmap_info *info;
+
+ rmnet_shs_wq_ep_lock_bh();
+ if (ssflow_shared) {
+ info = (struct rmnet_shs_mmap_info *) vmf->vma->vm_private_data;
+ if (info->data) {
+ page = virt_to_page(info->data);
+ get_page(page);
+ vmf->page = page;
+ } else {
+ rmnet_shs_wq_ep_unlock_bh();
+ return VM_FAULT_SIGSEGV;
+ }
+ } else {
+ rmnet_shs_wq_ep_unlock_bh();
+ return VM_FAULT_SIGSEGV;
}
rmnet_shs_wq_ep_unlock_bh();
return 0;
}
-static const struct vm_operations_struct rmnet_shs_vm_ops = {
+static const struct vm_operations_struct rmnet_shs_vm_ops_caps = {
+ .close = rmnet_shs_vm_close,
+ .open = rmnet_shs_vm_open,
+ .fault = rmnet_shs_vm_fault_caps,
+};
+
+static const struct vm_operations_struct rmnet_shs_vm_ops_g_flows = {
.close = rmnet_shs_vm_close,
.open = rmnet_shs_vm_open,
- .fault = rmnet_shs_vm_fault,
+ .fault = rmnet_shs_vm_fault_g_flows,
};
-static int rmnet_shs_mmap(struct file *filp, struct vm_area_struct *vma)
+static const struct vm_operations_struct rmnet_shs_vm_ops_ss_flows = {
+ .close = rmnet_shs_vm_close,
+ .open = rmnet_shs_vm_open,
+ .fault = rmnet_shs_vm_fault_ss_flows,
+};
+
+static int rmnet_shs_mmap_caps(struct file *filp, struct vm_area_struct *vma)
+{
+ vma->vm_ops = &rmnet_shs_vm_ops_caps;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+ vma->vm_private_data = filp->private_data;
+
+ return 0;
+}
+
+static int rmnet_shs_mmap_g_flows(struct file *filp, struct vm_area_struct *vma)
+{
+ vma->vm_ops = &rmnet_shs_vm_ops_g_flows;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+ vma->vm_private_data = filp->private_data;
+
+ return 0;
+}
+
+static int rmnet_shs_mmap_ss_flows(struct file *filp, struct vm_area_struct *vma)
{
- vma->vm_ops = &rmnet_shs_vm_ops;
+ vma->vm_ops = &rmnet_shs_vm_ops_ss_flows;
vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = filp->private_data;
@@ -226,9 +316,9 @@ static int rmnet_shs_release_caps(struct inode *inode, struct file *filp)
rmnet_shs_wq_ep_lock_bh();
if (cap_shared) {
info = filp->private_data;
- cap_shared = NULL;
free_page((unsigned long)info->data);
kfree(info);
+ cap_shared = NULL;
filp->private_data = NULL;
}
rmnet_shs_wq_ep_unlock_bh();
@@ -245,9 +335,9 @@ static int rmnet_shs_release_g_flows(struct inode *inode, struct file *filp)
rmnet_shs_wq_ep_lock_bh();
if (gflow_shared) {
info = filp->private_data;
- gflow_shared = NULL;
free_page((unsigned long)info->data);
kfree(info);
+ gflow_shared = NULL;
filp->private_data = NULL;
}
rmnet_shs_wq_ep_unlock_bh();
@@ -264,9 +354,9 @@ static int rmnet_shs_release_ss_flows(struct inode *inode, struct file *filp)
rmnet_shs_wq_ep_lock_bh();
if (ssflow_shared) {
info = filp->private_data;
- ssflow_shared = NULL;
free_page((unsigned long)info->data);
kfree(info);
+ ssflow_shared = NULL;
filp->private_data = NULL;
}
rmnet_shs_wq_ep_unlock_bh();
@@ -276,7 +366,7 @@ static int rmnet_shs_release_ss_flows(struct inode *inode, struct file *filp)
static const struct file_operations rmnet_shs_caps_fops = {
.owner = THIS_MODULE,
- .mmap = rmnet_shs_mmap,
+ .mmap = rmnet_shs_mmap_caps,
.open = rmnet_shs_open_caps,
.release = rmnet_shs_release_caps,
.read = rmnet_shs_read,
@@ -285,7 +375,7 @@ static const struct file_operations rmnet_shs_caps_fops = {
static const struct file_operations rmnet_shs_g_flows_fops = {
.owner = THIS_MODULE,
- .mmap = rmnet_shs_mmap,
+ .mmap = rmnet_shs_mmap_g_flows,
.open = rmnet_shs_open_g_flows,
.release = rmnet_shs_release_g_flows,
.read = rmnet_shs_read,
@@ -294,7 +384,7 @@ static const struct file_operations rmnet_shs_g_flows_fops = {
static const struct file_operations rmnet_shs_ss_flows_fops = {
.owner = THIS_MODULE,
- .mmap = rmnet_shs_mmap,
+ .mmap = rmnet_shs_mmap_ss_flows,
.open = rmnet_shs_open_ss_flows,
.release = rmnet_shs_release_ss_flows,
.read = rmnet_shs_read,