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

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.edu


Signed-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
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
 */

#include <linux/refcount.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/time.h>
@@ -28,7 +29,7 @@
#include "coda_int.h"

struct coda_vm_ops {
	atomic_t refcnt;
	refcount_t refcnt;
	struct file *coda_file;
	const struct vm_operations_struct *host_vm_ops;
	struct vm_operations_struct vm_ops;
@@ -98,7 +99,7 @@ coda_vm_open(struct vm_area_struct *vma)
	struct coda_vm_ops *cvm_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)
		cvm_ops->host_vm_ops->open(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)
		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;
		fput(cvm_ops->coda_file);
		kfree(cvm_ops);
@@ -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.close = coda_vm_close;
		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;
	}