FAILED: patch "[PATCH] ceph: fix NULL pointer dereference for req->r_session" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Possible dependencies:
5bd76b8de5b7 ("ceph: fix NULL pointer dereference for req->r_session") aa1d627207ca ("ceph: Use kcalloc for allocating multiple elements") 7acae6183cf3 ("ceph: fix possible NULL pointer dereference for req->r_session") 89d43d0551a8 ("ceph: put the requests/sessions when it fails to alloc memory")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 5bd76b8de5b74fa941a6eafee87728a0fe072267 Mon Sep 17 00:00:00 2001
From: Xiubo Li <[email protected]>
Date: Thu, 10 Nov 2022 21:01:59 +0800
Subject: [PATCH] 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.
fs/ceph/caps.c +12 -36
@@ -2248,7 +2248,6 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)struct ceph_mds_client *mdsc =ceph_sb_to_client (inode->i_sb)->mdsc;struct ceph_inode_info *ci =ceph_inode (inode);struct ceph_mds_request *req1 =NULL , *req2 =NULL ; -unsigned int max_sessions;int ret, err =0 ;spin_lock (&ci->i_unsafe_lock);
@@ -2266,28 +2265,24 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode) }spin_unlock (&ci->i_unsafe_lock); -/* -* The mdsc->max_sessions is unlikely to be changed -* mostly, here we will retry it by reallocating the -* sessions array memory to get rid of the mdsc->mutex -* lock. -*/ -retry: - max_sessions = mdsc->max_sessions; -/* * Trigger to flush the journal logs in all the relevant MDSes * manually, or in the worst case we must wait at most 5 seconds * to wait the journal logs to be flushed by the MDSes periodically. */ -if ((req1 || req2) &&likely (max_sessions)) { -struct ceph_mds_session **sessions =NULL ; -struct ceph_mds_session *s; +if (req1 || req2) {struct ceph_mds_request *req; +struct ceph_mds_session **sessions; +struct ceph_mds_session *s; +unsigned int max_sessions;int i; +mutex_lock (&mdsc->mutex); + max_sessions = mdsc->max_sessions; + sessions =kcalloc (max_sessions,sizeof (s),GFP_KERNEL );if (!sessions) { +mutex_unlock (&mdsc->mutex); err = -ENOMEM ; goto out; }
@@ -2299,16 +2294,6 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode) s = req->r_session;if (!s)continue ; -if (unlikely (s->s_mds >= max_sessions)) { -spin_unlock (&ci->i_unsafe_lock); -for (i =0 ; i < max_sessions; i++) { - s = sessions[i]; -if (s) -ceph_put_mds_session (s); - } -kfree (sessions); - goto retry; - }if (!sessions[s->s_mds]) { s =ceph_get_mds_session (s); sessions[s->s_mds] = s;
@@ -2321,16 +2306,6 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode) s = req->r_session;if (!s)continue ; -if (unlikely (s->s_mds >= max_sessions)) { -spin_unlock (&ci->i_unsafe_lock); -for (i =0 ; i < max_sessions; i++) { - s = sessions[i]; -if (s) -ceph_put_mds_session (s); - } -kfree (sessions); - goto retry; - }if (!sessions[s->s_mds]) { s =ceph_get_mds_session (s); sessions[s->s_mds] = s;
@@ -2342,11 +2317,12 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)/* the auth MDS */ spin_lock (&ci->i_ceph_lock);if (ci->i_auth_cap) { - s = ci->i_auth_cap->session; -if (!sessions[s->s_mds]) - sessions[s->s_mds] =ceph_get_mds_session (s); + s = ci->i_auth_cap->session; +if (!sessions[s->s_mds]) + sessions[s->s_mds] =ceph_get_mds_session (s); }spin_unlock (&ci->i_ceph_lock); +mutex_unlock (&mdsc->mutex);/* send flush mdlog request to MDSes */ for (i =0 ; i < max_sessions; i++) {