Commit 3997c01d authored by Elena Reshetova's avatar Elena Reshetova Committed by Ilya Dryomov

ceph: convert ceph_mds_session.s_ref 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 d6a3408a
...@@ -378,9 +378,9 @@ const char *ceph_session_state_name(int s) ...@@ -378,9 +378,9 @@ const char *ceph_session_state_name(int s)
static struct ceph_mds_session *get_session(struct ceph_mds_session *s) static struct ceph_mds_session *get_session(struct ceph_mds_session *s)
{ {
if (atomic_inc_not_zero(&s->s_ref)) { if (refcount_inc_not_zero(&s->s_ref)) {
dout("mdsc get_session %p %d -> %d\n", s, dout("mdsc get_session %p %d -> %d\n", s,
atomic_read(&s->s_ref)-1, atomic_read(&s->s_ref)); refcount_read(&s->s_ref)-1, refcount_read(&s->s_ref));
return s; return s;
} else { } else {
dout("mdsc get_session %p 0 -- FAIL", s); dout("mdsc get_session %p 0 -- FAIL", s);
...@@ -391,8 +391,8 @@ static struct ceph_mds_session *get_session(struct ceph_mds_session *s) ...@@ -391,8 +391,8 @@ static struct ceph_mds_session *get_session(struct ceph_mds_session *s)
void ceph_put_mds_session(struct ceph_mds_session *s) void ceph_put_mds_session(struct ceph_mds_session *s)
{ {
dout("mdsc put_session %p %d -> %d\n", s, dout("mdsc put_session %p %d -> %d\n", s,
atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); refcount_read(&s->s_ref), refcount_read(&s->s_ref)-1);
if (atomic_dec_and_test(&s->s_ref)) { if (refcount_dec_and_test(&s->s_ref)) {
if (s->s_auth.authorizer) if (s->s_auth.authorizer)
ceph_auth_destroy_authorizer(s->s_auth.authorizer); ceph_auth_destroy_authorizer(s->s_auth.authorizer);
kfree(s); kfree(s);
...@@ -411,7 +411,7 @@ struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc, ...@@ -411,7 +411,7 @@ struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc,
return NULL; return NULL;
session = mdsc->sessions[mds]; session = mdsc->sessions[mds];
dout("lookup_mds_session %p %d\n", session, dout("lookup_mds_session %p %d\n", session,
atomic_read(&session->s_ref)); refcount_read(&session->s_ref));
get_session(session); get_session(session);
return session; return session;
} }
...@@ -466,7 +466,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, ...@@ -466,7 +466,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
INIT_LIST_HEAD(&s->s_caps); INIT_LIST_HEAD(&s->s_caps);
s->s_nr_caps = 0; s->s_nr_caps = 0;
s->s_trim_caps = 0; s->s_trim_caps = 0;
atomic_set(&s->s_ref, 1); refcount_set(&s->s_ref, 1);
INIT_LIST_HEAD(&s->s_waiting); INIT_LIST_HEAD(&s->s_waiting);
INIT_LIST_HEAD(&s->s_unsafe); INIT_LIST_HEAD(&s->s_unsafe);
s->s_num_cap_releases = 0; s->s_num_cap_releases = 0;
...@@ -494,7 +494,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, ...@@ -494,7 +494,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
} }
mdsc->sessions[mds] = s; mdsc->sessions[mds] = s;
atomic_inc(&mdsc->num_sessions); atomic_inc(&mdsc->num_sessions);
atomic_inc(&s->s_ref); /* one ref to sessions[], one to caller */ refcount_inc(&s->s_ref); /* one ref to sessions[], one to caller */
ceph_con_open(&s->s_con, CEPH_ENTITY_TYPE_MDS, mds, ceph_con_open(&s->s_con, CEPH_ENTITY_TYPE_MDS, mds,
ceph_mdsmap_get_addr(mdsc->mdsmap, mds)); ceph_mdsmap_get_addr(mdsc->mdsmap, mds));
...@@ -3881,7 +3881,7 @@ static struct ceph_connection *con_get(struct ceph_connection *con) ...@@ -3881,7 +3881,7 @@ static struct ceph_connection *con_get(struct ceph_connection *con)
struct ceph_mds_session *s = con->private; struct ceph_mds_session *s = con->private;
if (get_session(s)) { if (get_session(s)) {
dout("mdsc con_get %p ok (%d)\n", s, atomic_read(&s->s_ref)); dout("mdsc con_get %p ok (%d)\n", s, refcount_read(&s->s_ref));
return con; return con;
} }
dout("mdsc con_get %p FAIL\n", s); dout("mdsc con_get %p FAIL\n", s);
...@@ -3892,7 +3892,7 @@ static void con_put(struct ceph_connection *con) ...@@ -3892,7 +3892,7 @@ static void con_put(struct ceph_connection *con)
{ {
struct ceph_mds_session *s = con->private; struct ceph_mds_session *s = con->private;
dout("mdsc con_put %p (%d)\n", s, atomic_read(&s->s_ref) - 1); dout("mdsc con_put %p (%d)\n", s, refcount_read(&s->s_ref) - 1);
ceph_put_mds_session(s); ceph_put_mds_session(s);
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/refcount.h>
#include <linux/ceph/types.h> #include <linux/ceph/types.h>
#include <linux/ceph/messenger.h> #include <linux/ceph/messenger.h>
...@@ -156,7 +157,7 @@ struct ceph_mds_session { ...@@ -156,7 +157,7 @@ struct ceph_mds_session {
unsigned long s_renew_requested; /* last time we sent a renew req */ unsigned long s_renew_requested; /* last time we sent a renew req */
u64 s_renew_seq; u64 s_renew_seq;
atomic_t s_ref; refcount_t s_ref;
struct list_head s_waiting; /* waiting requests */ struct list_head s_waiting; /* waiting requests */
struct list_head s_unsafe; /* unsafe requests */ struct list_head s_unsafe; /* unsafe requests */
}; };
...@@ -373,7 +374,7 @@ __ceph_lookup_mds_session(struct ceph_mds_client *, int mds); ...@@ -373,7 +374,7 @@ __ceph_lookup_mds_session(struct ceph_mds_client *, int mds);
static inline struct ceph_mds_session * static inline struct ceph_mds_session *
ceph_get_mds_session(struct ceph_mds_session *s) ceph_get_mds_session(struct ceph_mds_session *s)
{ {
atomic_inc(&s->s_ref); refcount_inc(&s->s_ref);
return s; return s;
} }
......
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