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

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
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1389,7 +1389,7 @@ static void __ceph_flush_snaps(struct ceph_inode_info *ci,
		first_tid = cf->tid + 1;

		capsnap = container_of(cf, struct ceph_cap_snap, cap_flush);
		atomic_inc(&capsnap->nref);
		refcount_inc(&capsnap->nref);
		spin_unlock(&ci->i_ceph_lock);

		dout("__flush_snaps %p capsnap %p tid %llu %s\n",
@@ -2202,7 +2202,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc,
			     inode, capsnap, cf->tid,
			     ceph_cap_string(capsnap->dirty));

			atomic_inc(&capsnap->nref);
			refcount_inc(&capsnap->nref);
			spin_unlock(&ci->i_ceph_lock);

			ret = __send_flush_snap(inode, session, capsnap, cap->mseq,
+1 −1
Original line number Diff line number Diff line
@@ -519,7 +519,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
	     capsnap->need_flush ? "" : "no_flush");
	ihold(inode);

	atomic_set(&capsnap->nref, 1);
	refcount_set(&capsnap->nref, 1);
	INIT_LIST_HEAD(&capsnap->ci_item);

	capsnap->follows = old_snapc->seq;
+3 −2
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/writeback.h>
#include <linux/slab.h>
#include <linux/posix_acl.h>
#include <linux/refcount.h>

#include <linux/ceph/libceph.h>

@@ -162,7 +163,7 @@ struct ceph_cap_flush {
 * data before flushing the snapped state (tracked here) back to the MDS.
 */
struct ceph_cap_snap {
	atomic_t nref;
	refcount_t nref;
	struct list_head ci_item;

	struct ceph_cap_flush cap_flush;
@@ -191,7 +192,7 @@ struct ceph_cap_snap {

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)
			ceph_buffer_put(capsnap->xattr_blob);
		kfree(capsnap);