libceph: convert ceph_pagelist.refcnt from atomic_t to refcount_t
authorElena Reshetova <elena.reshetova@intel.com>
Fri, 17 Mar 2017 12:10:29 +0000 (14:10 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Thu, 4 May 2017 07:19:19 +0000 (09:19 +0200)
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: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/mds_client.c
include/linux/ceph/pagelist.h
net/ceph/pagelist.c

index 074490542b4ce39ac3b6d56f88c453b05cda0281..b16f1cf552a86da2c07251e330ca7bd8eb8f8136 100644 (file)
@@ -1991,7 +1991,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
 
        if (req->r_pagelist) {
                struct ceph_pagelist *pagelist = req->r_pagelist;
-               atomic_inc(&pagelist->refcnt);
+               refcount_inc(&pagelist->refcnt);
                ceph_msg_data_add_pagelist(msg, pagelist);
                msg->hdr.data_len = cpu_to_le32(pagelist->length);
        } else {
index 13d71fe18b0cf54f6097242fd08b9a30c6c48bbe..75a7db21457de5e6fce1e75cfca3749ff539057c 100644 (file)
@@ -2,7 +2,7 @@
 #define __FS_CEPH_PAGELIST_H
 
 #include <asm/byteorder.h>
-#include <linux/atomic.h>
+#include <linux/refcount.h>
 #include <linux/list.h>
 #include <linux/types.h>
 
@@ -13,7 +13,7 @@ struct ceph_pagelist {
        size_t room;
        struct list_head free_list;
        size_t num_pages_free;
-       atomic_t refcnt;
+       refcount_t refcnt;
 };
 
 struct ceph_pagelist_cursor {
@@ -30,7 +30,7 @@ static inline void ceph_pagelist_init(struct ceph_pagelist *pl)
        pl->room = 0;
        INIT_LIST_HEAD(&pl->free_list);
        pl->num_pages_free = 0;
-       atomic_set(&pl->refcnt, 1);
+       refcount_set(&pl->refcnt, 1);
 }
 
 extern void ceph_pagelist_release(struct ceph_pagelist *pl);
index 6864007e64fc3236f6d118f8a4a1869255bbba92..ce09f73be759c562cb9ffe093eb1c44350c8adde 100644 (file)
@@ -16,7 +16,7 @@ static void ceph_pagelist_unmap_tail(struct ceph_pagelist *pl)
 
 void ceph_pagelist_release(struct ceph_pagelist *pl)
 {
-       if (!atomic_dec_and_test(&pl->refcnt))
+       if (!refcount_dec_and_test(&pl->refcnt))
                return;
        ceph_pagelist_unmap_tail(pl);
        while (!list_empty(&pl->head)) {