mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 05:04:02 +02:00
ceph: fix use-after-dereference of NULL ci in __ceph_remove_cap()
The NULL check for "ci" in __ceph_remove_cap() was dead code because ci was dereferenced via &ci->netfs.inode before the check, and cap->session was dereferenced via session->s_mdsc->fsc->client even earlier. On a double-remove, both cap->ci and cap->session are set to NULL by the first call, so the second call would crash before ever reaching the guard. Move ci, session, cl, and inode initializations after the NULL check so that the early-return actually works. Signed-off-by: Xiubo Li <xiubo.li@clyso.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
af59562a5b
commit
a354d7eaa1
|
|
@ -1129,18 +1129,21 @@ int ceph_is_any_caps(struct inode *inode)
|
|||
*/
|
||||
void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
|
||||
{
|
||||
struct ceph_mds_session *session = cap->session;
|
||||
struct ceph_client *cl = session->s_mdsc->fsc->client;
|
||||
struct ceph_inode_info *ci = cap->ci;
|
||||
struct inode *inode = &ci->netfs.inode;
|
||||
struct ceph_mds_session *session;
|
||||
struct ceph_client *cl;
|
||||
struct ceph_inode_info *ci;
|
||||
struct inode *inode;
|
||||
struct ceph_mds_client *mdsc;
|
||||
int removed = 0;
|
||||
|
||||
/* 'ci' being NULL means the remove have already occurred */
|
||||
if (!ci) {
|
||||
doutc(cl, "inode is NULL\n");
|
||||
ci = cap->ci;
|
||||
if (!ci)
|
||||
return;
|
||||
}
|
||||
|
||||
session = cap->session;
|
||||
cl = session->s_mdsc->fsc->client;
|
||||
inode = &ci->netfs.inode;
|
||||
|
||||
lockdep_assert_held(&ci->i_ceph_lock);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user