Skip to content

Commit 5bd76b8

Browse files
lxbszidryomov
authored andcommitted
ceph: fix NULL pointer dereference for req->r_session
The request's r_session maybe changed when it was forwarded or resent. Both the forwarding and resending cases the requests will be protected by the mdsc->mutex. Cc: [email protected] Link: https://bugzilla.redhat.com/show_bug.cgi?id=2137955 Signed-off-by: Xiubo Li <[email protected]> Reviewed-by: Ilya Dryomov <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 51884d1 commit 5bd76b8

File tree

1 file changed

+12
-36
lines changed

1 file changed

+12
-36
lines changed

fs/ceph/caps.c

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,7 +2248,6 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
22482248
struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
22492249
struct ceph_inode_info *ci = ceph_inode(inode);
22502250
struct ceph_mds_request *req1 = NULL, *req2 = NULL;
2251-
unsigned int max_sessions;
22522251
int ret, err = 0;
22532252

22542253
spin_lock(&ci->i_unsafe_lock);
@@ -2266,28 +2265,24 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
22662265
}
22672266
spin_unlock(&ci->i_unsafe_lock);
22682267

2269-
/*
2270-
* The mdsc->max_sessions is unlikely to be changed
2271-
* mostly, here we will retry it by reallocating the
2272-
* sessions array memory to get rid of the mdsc->mutex
2273-
* lock.
2274-
*/
2275-
retry:
2276-
max_sessions = mdsc->max_sessions;
2277-
22782268
/*
22792269
* Trigger to flush the journal logs in all the relevant MDSes
22802270
* manually, or in the worst case we must wait at most 5 seconds
22812271
* to wait the journal logs to be flushed by the MDSes periodically.
22822272
*/
2283-
if ((req1 || req2) && likely(max_sessions)) {
2284-
struct ceph_mds_session **sessions = NULL;
2285-
struct ceph_mds_session *s;
2273+
if (req1 || req2) {
22862274
struct ceph_mds_request *req;
2275+
struct ceph_mds_session **sessions;
2276+
struct ceph_mds_session *s;
2277+
unsigned int max_sessions;
22872278
int i;
22882279

2280+
mutex_lock(&mdsc->mutex);
2281+
max_sessions = mdsc->max_sessions;
2282+
22892283
sessions = kcalloc(max_sessions, sizeof(s), GFP_KERNEL);
22902284
if (!sessions) {
2285+
mutex_unlock(&mdsc->mutex);
22912286
err = -ENOMEM;
22922287
goto out;
22932288
}
@@ -2299,16 +2294,6 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
22992294
s = req->r_session;
23002295
if (!s)
23012296
continue;
2302-
if (unlikely(s->s_mds >= max_sessions)) {
2303-
spin_unlock(&ci->i_unsafe_lock);
2304-
for (i = 0; i < max_sessions; i++) {
2305-
s = sessions[i];
2306-
if (s)
2307-
ceph_put_mds_session(s);
2308-
}
2309-
kfree(sessions);
2310-
goto retry;
2311-
}
23122297
if (!sessions[s->s_mds]) {
23132298
s = ceph_get_mds_session(s);
23142299
sessions[s->s_mds] = s;
@@ -2321,16 +2306,6 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
23212306
s = req->r_session;
23222307
if (!s)
23232308
continue;
2324-
if (unlikely(s->s_mds >= max_sessions)) {
2325-
spin_unlock(&ci->i_unsafe_lock);
2326-
for (i = 0; i < max_sessions; i++) {
2327-
s = sessions[i];
2328-
if (s)
2329-
ceph_put_mds_session(s);
2330-
}
2331-
kfree(sessions);
2332-
goto retry;
2333-
}
23342309
if (!sessions[s->s_mds]) {
23352310
s = ceph_get_mds_session(s);
23362311
sessions[s->s_mds] = s;
@@ -2342,11 +2317,12 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
23422317
/* the auth MDS */
23432318
spin_lock(&ci->i_ceph_lock);
23442319
if (ci->i_auth_cap) {
2345-
s = ci->i_auth_cap->session;
2346-
if (!sessions[s->s_mds])
2347-
sessions[s->s_mds] = ceph_get_mds_session(s);
2320+
s = ci->i_auth_cap->session;
2321+
if (!sessions[s->s_mds])
2322+
sessions[s->s_mds] = ceph_get_mds_session(s);
23482323
}
23492324
spin_unlock(&ci->i_ceph_lock);
2325+
mutex_unlock(&mdsc->mutex);
23502326

23512327
/* send flush mdlog request to MDSes */
23522328
for (i = 0; i < max_sessions; i++) {

0 commit comments

Comments
 (0)