SUNRPC: Fix potential memory corruption
[ Upstream commit c2dc3e5fad13aca5d7bdf4bcb52b1a1d707c8555 ]
We really should not call rpc_wake_up_queued_task_set_status() with
xprt->snd_task as an argument unless we are certain that is actually an
rpc_task.
Fixes: 0445f92c5d
("SUNRPC: Fix disconnection races")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
be09cbd6a3
commit
9ee7b45edd
@ -419,6 +419,7 @@ void xprt_unlock_connect(struct rpc_xprt *, void *);
|
|||||||
#define XPRT_CONGESTED (9)
|
#define XPRT_CONGESTED (9)
|
||||||
#define XPRT_CWND_WAIT (10)
|
#define XPRT_CWND_WAIT (10)
|
||||||
#define XPRT_WRITE_SPACE (11)
|
#define XPRT_WRITE_SPACE (11)
|
||||||
|
#define XPRT_SND_IS_COOKIE (12)
|
||||||
|
|
||||||
static inline void xprt_set_connected(struct rpc_xprt *xprt)
|
static inline void xprt_set_connected(struct rpc_xprt *xprt)
|
||||||
{
|
{
|
||||||
|
@ -729,9 +729,9 @@ void xprt_force_disconnect(struct rpc_xprt *xprt)
|
|||||||
/* Try to schedule an autoclose RPC call */
|
/* Try to schedule an autoclose RPC call */
|
||||||
if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
|
if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
|
||||||
queue_work(xprtiod_workqueue, &xprt->task_cleanup);
|
queue_work(xprtiod_workqueue, &xprt->task_cleanup);
|
||||||
else if (xprt->snd_task)
|
else if (xprt->snd_task && !test_bit(XPRT_SND_IS_COOKIE, &xprt->state))
|
||||||
rpc_wake_up_queued_task_set_status(&xprt->pending,
|
rpc_wake_up_queued_task_set_status(&xprt->pending,
|
||||||
xprt->snd_task, -ENOTCONN);
|
xprt->snd_task, -ENOTCONN);
|
||||||
spin_unlock(&xprt->transport_lock);
|
spin_unlock(&xprt->transport_lock);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xprt_force_disconnect);
|
EXPORT_SYMBOL_GPL(xprt_force_disconnect);
|
||||||
@ -820,6 +820,7 @@ bool xprt_lock_connect(struct rpc_xprt *xprt,
|
|||||||
goto out;
|
goto out;
|
||||||
if (xprt->snd_task != task)
|
if (xprt->snd_task != task)
|
||||||
goto out;
|
goto out;
|
||||||
|
set_bit(XPRT_SND_IS_COOKIE, &xprt->state);
|
||||||
xprt->snd_task = cookie;
|
xprt->snd_task = cookie;
|
||||||
ret = true;
|
ret = true;
|
||||||
out:
|
out:
|
||||||
@ -835,6 +836,7 @@ void xprt_unlock_connect(struct rpc_xprt *xprt, void *cookie)
|
|||||||
if (!test_bit(XPRT_LOCKED, &xprt->state))
|
if (!test_bit(XPRT_LOCKED, &xprt->state))
|
||||||
goto out;
|
goto out;
|
||||||
xprt->snd_task =NULL;
|
xprt->snd_task =NULL;
|
||||||
|
clear_bit(XPRT_SND_IS_COOKIE, &xprt->state);
|
||||||
xprt->ops->release_xprt(xprt, NULL);
|
xprt->ops->release_xprt(xprt, NULL);
|
||||||
xprt_schedule_autodisconnect(xprt);
|
xprt_schedule_autodisconnect(xprt);
|
||||||
out:
|
out:
|
||||||
|
Loading…
Reference in New Issue
Block a user