Commit 805692d0 authored by Elena Reshetova's avatar Elena Reshetova Committed by Ilya Dryomov

ceph: convert ceph_cap_snap.nref 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: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarDavid Windsor <dwindsor@gmail.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 3997c01d
...@@ -1389,7 +1389,7 @@ static void __ceph_flush_snaps(struct ceph_inode_info *ci, ...@@ -1389,7 +1389,7 @@ static void __ceph_flush_snaps(struct ceph_inode_info *ci,
first_tid = cf->tid + 1; first_tid = cf->tid + 1;
capsnap = container_of(cf, struct ceph_cap_snap, cap_flush); capsnap = container_of(cf, struct ceph_cap_snap, cap_flush);
atomic_inc(&capsnap->nref); refcount_inc(&capsnap->nref);
spin_unlock(&ci->i_ceph_lock); spin_unlock(&ci->i_ceph_lock);
dout("__flush_snaps %p capsnap %p tid %llu %s\n", dout("__flush_snaps %p capsnap %p tid %llu %s\n",
...@@ -2202,7 +2202,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, ...@@ -2202,7 +2202,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc,
inode, capsnap, cf->tid, inode, capsnap, cf->tid,
ceph_cap_string(capsnap->dirty)); ceph_cap_string(capsnap->dirty));
atomic_inc(&capsnap->nref); refcount_inc(&capsnap->nref);
spin_unlock(&ci->i_ceph_lock); spin_unlock(&ci->i_ceph_lock);
ret = __send_flush_snap(inode, session, capsnap, cap->mseq, ret = __send_flush_snap(inode, session, capsnap, cap->mseq,
......
...@@ -519,7 +519,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) ...@@ -519,7 +519,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
capsnap->need_flush ? "" : "no_flush"); capsnap->need_flush ? "" : "no_flush");
ihold(inode); ihold(inode);
atomic_set(&capsnap->nref, 1); refcount_set(&capsnap->nref, 1);
INIT_LIST_HEAD(&capsnap->ci_item); INIT_LIST_HEAD(&capsnap->ci_item);
capsnap->follows = old_snapc->seq; capsnap->follows = old_snapc->seq;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/posix_acl.h> #include <linux/posix_acl.h>
#include <linux/refcount.h>
#include <linux/ceph/libceph.h> #include <linux/ceph/libceph.h>
...@@ -162,7 +163,7 @@ struct ceph_cap_flush { ...@@ -162,7 +163,7 @@ struct ceph_cap_flush {
* data before flushing the snapped state (tracked here) back to the MDS. * data before flushing the snapped state (tracked here) back to the MDS.
*/ */
struct ceph_cap_snap { struct ceph_cap_snap {
atomic_t nref; refcount_t nref;
struct list_head ci_item; struct list_head ci_item;
struct ceph_cap_flush cap_flush; struct ceph_cap_flush cap_flush;
...@@ -191,7 +192,7 @@ struct ceph_cap_snap { ...@@ -191,7 +192,7 @@ struct ceph_cap_snap {
static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap)
{ {
if (atomic_dec_and_test(&capsnap->nref)) { if (refcount_dec_and_test(&capsnap->nref)) {
if (capsnap->xattr_blob) if (capsnap->xattr_blob)
ceph_buffer_put(capsnap->xattr_blob); ceph_buffer_put(capsnap->xattr_blob);
kfree(capsnap); kfree(capsnap);
......
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