Skip to content

Commit df60446

Browse files
scottmayhewchucklever
authored andcommitted
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: 11a60d1 ("nfsd: add a "GetVersion" upcall for nfsdcld") Signed-off-by: Scott Mayhew <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 94415b0 commit df60446

File tree

1 file changed

+11
-13
lines changed

1 file changed

+11
-13
lines changed

fs/nfsd/nfs4recover.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -747,13 +747,11 @@ struct cld_upcall {
747747
};
748748

749749
static int
750-
__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg)
750+
__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn)
751751
{
752752
int ret;
753753
struct rpc_pipe_msg msg;
754754
struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_u);
755-
struct nfsd_net *nn = net_generic(pipe->dentry->d_sb->s_fs_info,
756-
nfsd_net_id);
757755

758756
memset(&msg, 0, sizeof(msg));
759757
msg.data = cmsg;
@@ -773,7 +771,7 @@ __cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg)
773771
}
774772

775773
static int
776-
cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg)
774+
cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn)
777775
{
778776
int ret;
779777

@@ -782,7 +780,7 @@ cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg)
782780
* upcalls queued.
783781
*/
784782
do {
785-
ret = __cld_pipe_upcall(pipe, cmsg);
783+
ret = __cld_pipe_upcall(pipe, cmsg, nn);
786784
} while (ret == -EAGAIN);
787785

788786
return ret;
@@ -1115,7 +1113,7 @@ nfsd4_cld_create(struct nfs4_client *clp)
11151113
memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
11161114
clp->cl_name.len);
11171115

1118-
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
1116+
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
11191117
if (!ret) {
11201118
ret = cup->cu_u.cu_msg.cm_status;
11211119
set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
@@ -1180,7 +1178,7 @@ nfsd4_cld_create_v2(struct nfs4_client *clp)
11801178
} else
11811179
cmsg->cm_u.cm_clntinfo.cc_princhash.cp_len = 0;
11821180

1183-
ret = cld_pipe_upcall(cn->cn_pipe, cmsg);
1181+
ret = cld_pipe_upcall(cn->cn_pipe, cmsg, nn);
11841182
if (!ret) {
11851183
ret = cmsg->cm_status;
11861184
set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
@@ -1218,7 +1216,7 @@ nfsd4_cld_remove(struct nfs4_client *clp)
12181216
memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
12191217
clp->cl_name.len);
12201218

1221-
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
1219+
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
12221220
if (!ret) {
12231221
ret = cup->cu_u.cu_msg.cm_status;
12241222
clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
@@ -1261,7 +1259,7 @@ nfsd4_cld_check_v0(struct nfs4_client *clp)
12611259
memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
12621260
clp->cl_name.len);
12631261

1264-
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
1262+
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
12651263
if (!ret) {
12661264
ret = cup->cu_u.cu_msg.cm_status;
12671265
set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
@@ -1404,7 +1402,7 @@ nfsd4_cld_grace_start(struct nfsd_net *nn)
14041402
}
14051403

14061404
cup->cu_u.cu_msg.cm_cmd = Cld_GraceStart;
1407-
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
1405+
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
14081406
if (!ret)
14091407
ret = cup->cu_u.cu_msg.cm_status;
14101408

@@ -1432,7 +1430,7 @@ nfsd4_cld_grace_done_v0(struct nfsd_net *nn)
14321430

14331431
cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone;
14341432
cup->cu_u.cu_msg.cm_u.cm_gracetime = nn->boot_time;
1435-
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
1433+
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
14361434
if (!ret)
14371435
ret = cup->cu_u.cu_msg.cm_status;
14381436

@@ -1460,7 +1458,7 @@ nfsd4_cld_grace_done(struct nfsd_net *nn)
14601458
}
14611459

14621460
cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone;
1463-
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
1461+
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
14641462
if (!ret)
14651463
ret = cup->cu_u.cu_msg.cm_status;
14661464

@@ -1524,7 +1522,7 @@ nfsd4_cld_get_version(struct nfsd_net *nn)
15241522
goto out_err;
15251523
}
15261524
cup->cu_u.cu_msg.cm_cmd = Cld_GetVersion;
1527-
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
1525+
ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
15281526
if (!ret) {
15291527
ret = cup->cu_u.cu_msg.cm_status;
15301528
if (ret)

0 commit comments

Comments
 (0)