Commit 1077c285 authored by Xiyu Yang's avatar Xiyu Yang Committed by Linus Torvalds

coda: convert from atomic_t to refcount_t on coda_vm_ops->refcnt

refcount_t type and corresponding API can protect refcounters from
accidental underflow and overflow and further use-after-free situations.

Link: https://lkml.kernel.org/r/20210908140308.18491-8-jaharkes@cs.cmu.eduSigned-off-by: default avatarXiyu Yang <xiyuyang19@fudan.edu.cn>
Signed-off-by: default avatarXin Tan <tanxin.ctf@gmail.com>
Signed-off-by: default avatarJan Harkes <jaharkes@cs.cmu.edu>
Cc: Alex Shi <alex.shi@linux.alibaba.com>
Cc: Jing Yangyang <jing.yangyang@zte.com.cn>
Cc: Zeal Robot <zealci@zte.com.cn>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 5a646fb3
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>. * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
*/ */
#include <linux/refcount.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/time.h> #include <linux/time.h>
...@@ -28,7 +29,7 @@ ...@@ -28,7 +29,7 @@
#include "coda_int.h" #include "coda_int.h"
struct coda_vm_ops { struct coda_vm_ops {
atomic_t refcnt; refcount_t refcnt;
struct file *coda_file; struct file *coda_file;
const struct vm_operations_struct *host_vm_ops; const struct vm_operations_struct *host_vm_ops;
struct vm_operations_struct vm_ops; struct vm_operations_struct vm_ops;
...@@ -98,7 +99,7 @@ coda_vm_open(struct vm_area_struct *vma) ...@@ -98,7 +99,7 @@ coda_vm_open(struct vm_area_struct *vma)
struct coda_vm_ops *cvm_ops = struct coda_vm_ops *cvm_ops =
container_of(vma->vm_ops, struct coda_vm_ops, vm_ops); container_of(vma->vm_ops, struct coda_vm_ops, vm_ops);
atomic_inc(&cvm_ops->refcnt); refcount_inc(&cvm_ops->refcnt);
if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->open) if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->open)
cvm_ops->host_vm_ops->open(vma); cvm_ops->host_vm_ops->open(vma);
...@@ -113,7 +114,7 @@ coda_vm_close(struct vm_area_struct *vma) ...@@ -113,7 +114,7 @@ coda_vm_close(struct vm_area_struct *vma)
if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->close) if (cvm_ops->host_vm_ops && cvm_ops->host_vm_ops->close)
cvm_ops->host_vm_ops->close(vma); cvm_ops->host_vm_ops->close(vma);
if (atomic_dec_and_test(&cvm_ops->refcnt)) { if (refcount_dec_and_test(&cvm_ops->refcnt)) {
vma->vm_ops = cvm_ops->host_vm_ops; vma->vm_ops = cvm_ops->host_vm_ops;
fput(cvm_ops->coda_file); fput(cvm_ops->coda_file);
kfree(cvm_ops); kfree(cvm_ops);
...@@ -189,7 +190,7 @@ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma) ...@@ -189,7 +190,7 @@ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma)
cvm_ops->vm_ops.open = coda_vm_open; cvm_ops->vm_ops.open = coda_vm_open;
cvm_ops->vm_ops.close = coda_vm_close; cvm_ops->vm_ops.close = coda_vm_close;
cvm_ops->coda_file = coda_file; cvm_ops->coda_file = coda_file;
atomic_set(&cvm_ops->refcnt, 1); refcount_set(&cvm_ops->refcnt, 1);
vma->vm_ops = &cvm_ops->vm_ops; vma->vm_ops = &cvm_ops->vm_ops;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment