diff options
| author | Elena Reshetova <elena.reshetova@intel.com> | 2017-03-03 04:04:04 -0500 |
|---|---|---|
| committer | Miklos Szeredi <mszeredi@redhat.com> | 2017-04-18 10:58:37 -0400 |
| commit | ec99f6d31f2590a4c0ff2dae8fb1fa27f0647a42 (patch) | |
| tree | 21d44ad6c09ba6799248e53fe85596a3a6d2596e | |
| parent | 4e8c2eb54327a6f8b0ef6d6afb28ab24b721dbe0 (diff) | |
fuse: convert fuse_req.count from atomic_t to refcount_t
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
| -rw-r--r-- | fs/fuse/dev.c | 9 | ||||
| -rw-r--r-- | fs/fuse/fuse_i.h | 2 |
2 files changed, 5 insertions, 6 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index b681b43c766e..5e815072be1b 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
| @@ -45,7 +45,7 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages, | |||
| 45 | INIT_LIST_HEAD(&req->list); | 45 | INIT_LIST_HEAD(&req->list); |
| 46 | INIT_LIST_HEAD(&req->intr_entry); | 46 | INIT_LIST_HEAD(&req->intr_entry); |
| 47 | init_waitqueue_head(&req->waitq); | 47 | init_waitqueue_head(&req->waitq); |
| 48 | atomic_set(&req->count, 1); | 48 | refcount_set(&req->count, 1); |
| 49 | req->pages = pages; | 49 | req->pages = pages; |
| 50 | req->page_descs = page_descs; | 50 | req->page_descs = page_descs; |
| 51 | req->max_pages = npages; | 51 | req->max_pages = npages; |
| @@ -102,14 +102,13 @@ void fuse_request_free(struct fuse_req *req) | |||
| 102 | 102 | ||
| 103 | void __fuse_get_request(struct fuse_req *req) | 103 | void __fuse_get_request(struct fuse_req *req) |
| 104 | { | 104 | { |
| 105 | atomic_inc(&req->count); | 105 | refcount_inc(&req->count); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | /* Must be called with > 1 refcount */ | 108 | /* Must be called with > 1 refcount */ |
| 109 | static void __fuse_put_request(struct fuse_req *req) | 109 | static void __fuse_put_request(struct fuse_req *req) |
| 110 | { | 110 | { |
| 111 | BUG_ON(atomic_read(&req->count) < 2); | 111 | refcount_dec(&req->count); |
| 112 | atomic_dec(&req->count); | ||
| 113 | } | 112 | } |
| 114 | 113 | ||
| 115 | static void fuse_req_init_context(struct fuse_req *req) | 114 | static void fuse_req_init_context(struct fuse_req *req) |
| @@ -264,7 +263,7 @@ struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, | |||
| 264 | 263 | ||
| 265 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) | 264 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) |
| 266 | { | 265 | { |
| 267 | if (atomic_dec_and_test(&req->count)) { | 266 | if (refcount_dec_and_test(&req->count)) { |
| 268 | if (test_bit(FR_BACKGROUND, &req->flags)) { | 267 | if (test_bit(FR_BACKGROUND, &req->flags)) { |
| 269 | /* | 268 | /* |
| 270 | * We get here in the unlikely case that a background | 269 | * We get here in the unlikely case that a background |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 1d6d67e64f49..9d4374032290 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
| @@ -307,7 +307,7 @@ struct fuse_req { | |||
| 307 | struct list_head intr_entry; | 307 | struct list_head intr_entry; |
| 308 | 308 | ||
| 309 | /** refcount */ | 309 | /** refcount */ |
| 310 | atomic_t count; | 310 | refcount_t count; |
| 311 | 311 | ||
| 312 | /** Unique ID for the interrupt request */ | 312 | /** Unique ID for the interrupt request */ |
| 313 | u64 intr_unique; | 313 | u64 intr_unique; |
