mirror of
https://github.com/torvalds/linux
synced 2024-10-16 00:10:42 +00:00
nfsd: avoid a NULL dereference in __cld_pipe_upcall()
If the rpc_pipefs is unmounted, then the rpc_pipe->dentry becomes NULL
and dereferencing the dentry->d_sb will trigger an oops. The only
reason we're doing that is to determine the nfsd_net, which could
instead be passed in by the caller. So do that instead.
Fixes: 11a60d1592
("nfsd: add a "GetVersion" upcall for nfsdcld")
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
94415b06eb
commit
df60446cd1
|
@ -747,13 +747,11 @@ struct cld_upcall {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg)
|
__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct rpc_pipe_msg msg;
|
struct rpc_pipe_msg msg;
|
||||||
struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_u);
|
struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_u);
|
||||||
struct nfsd_net *nn = net_generic(pipe->dentry->d_sb->s_fs_info,
|
|
||||||
nfsd_net_id);
|
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.data = cmsg;
|
msg.data = cmsg;
|
||||||
|
@ -773,7 +771,7 @@ __cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg)
|
cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -782,7 +780,7 @@ cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg)
|
||||||
* upcalls queued.
|
* upcalls queued.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
ret = __cld_pipe_upcall(pipe, cmsg);
|
ret = __cld_pipe_upcall(pipe, cmsg, nn);
|
||||||
} while (ret == -EAGAIN);
|
} while (ret == -EAGAIN);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1115,7 +1113,7 @@ nfsd4_cld_create(struct nfs4_client *clp)
|
||||||
memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
|
memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
|
||||||
clp->cl_name.len);
|
clp->cl_name.len);
|
||||||
|
|
||||||
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
|
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
ret = cup->cu_u.cu_msg.cm_status;
|
ret = cup->cu_u.cu_msg.cm_status;
|
||||||
set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
|
set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
|
||||||
|
@ -1180,7 +1178,7 @@ nfsd4_cld_create_v2(struct nfs4_client *clp)
|
||||||
} else
|
} else
|
||||||
cmsg->cm_u.cm_clntinfo.cc_princhash.cp_len = 0;
|
cmsg->cm_u.cm_clntinfo.cc_princhash.cp_len = 0;
|
||||||
|
|
||||||
ret = cld_pipe_upcall(cn->cn_pipe, cmsg);
|
ret = cld_pipe_upcall(cn->cn_pipe, cmsg, nn);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
ret = cmsg->cm_status;
|
ret = cmsg->cm_status;
|
||||||
set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
|
set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
|
||||||
|
@ -1218,7 +1216,7 @@ nfsd4_cld_remove(struct nfs4_client *clp)
|
||||||
memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
|
memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
|
||||||
clp->cl_name.len);
|
clp->cl_name.len);
|
||||||
|
|
||||||
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
|
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
ret = cup->cu_u.cu_msg.cm_status;
|
ret = cup->cu_u.cu_msg.cm_status;
|
||||||
clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
|
clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
|
||||||
|
@ -1261,7 +1259,7 @@ nfsd4_cld_check_v0(struct nfs4_client *clp)
|
||||||
memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
|
memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
|
||||||
clp->cl_name.len);
|
clp->cl_name.len);
|
||||||
|
|
||||||
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
|
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
ret = cup->cu_u.cu_msg.cm_status;
|
ret = cup->cu_u.cu_msg.cm_status;
|
||||||
set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
|
set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
|
||||||
|
@ -1404,7 +1402,7 @@ nfsd4_cld_grace_start(struct nfsd_net *nn)
|
||||||
}
|
}
|
||||||
|
|
||||||
cup->cu_u.cu_msg.cm_cmd = Cld_GraceStart;
|
cup->cu_u.cu_msg.cm_cmd = Cld_GraceStart;
|
||||||
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
|
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = cup->cu_u.cu_msg.cm_status;
|
ret = cup->cu_u.cu_msg.cm_status;
|
||||||
|
|
||||||
|
@ -1432,7 +1430,7 @@ nfsd4_cld_grace_done_v0(struct nfsd_net *nn)
|
||||||
|
|
||||||
cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone;
|
cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone;
|
||||||
cup->cu_u.cu_msg.cm_u.cm_gracetime = nn->boot_time;
|
cup->cu_u.cu_msg.cm_u.cm_gracetime = nn->boot_time;
|
||||||
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
|
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = cup->cu_u.cu_msg.cm_status;
|
ret = cup->cu_u.cu_msg.cm_status;
|
||||||
|
|
||||||
|
@ -1460,7 +1458,7 @@ nfsd4_cld_grace_done(struct nfsd_net *nn)
|
||||||
}
|
}
|
||||||
|
|
||||||
cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone;
|
cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone;
|
||||||
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
|
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = cup->cu_u.cu_msg.cm_status;
|
ret = cup->cu_u.cu_msg.cm_status;
|
||||||
|
|
||||||
|
@ -1524,7 +1522,7 @@ nfsd4_cld_get_version(struct nfsd_net *nn)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
cup->cu_u.cu_msg.cm_cmd = Cld_GetVersion;
|
cup->cu_u.cu_msg.cm_cmd = Cld_GetVersion;
|
||||||
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
|
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
ret = cup->cu_u.cu_msg.cm_status;
|
ret = cup->cu_u.cu_msg.cm_status;
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in a new issue