NFSD: Avoid calling OPDESC() with ops->opnum == OP_ILLEGAL
[ Upstream commit804d8e0a6e
] OPDESC() simply indexes into nfsd4_ops[] by the op's operation number, without range checking that value. It assumes callers are careful to avoid calling it with an out-of-bounds opnum value. nfsd4_decode_compound() is not so careful, and can invoke OPDESC() with opnum set to OP_ILLEGAL, which is 10044 -- well beyond the end of nfsd4_ops[]. Reported-by: Jeff Layton <jlayton@kernel.org> Fixes:f4f9ef4a1b
("nfsd4: opdesc will be useful outside nfs4proc.c") Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
0d2a6a508b
commit
ffcbcf0875
@ -2417,10 +2417,12 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
|||||||
for (i = 0; i < argp->opcnt; i++) {
|
for (i = 0; i < argp->opcnt; i++) {
|
||||||
op = &argp->ops[i];
|
op = &argp->ops[i];
|
||||||
op->replay = NULL;
|
op->replay = NULL;
|
||||||
|
op->opdesc = NULL;
|
||||||
|
|
||||||
if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
|
if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
|
||||||
return false;
|
return false;
|
||||||
if (nfsd4_opnum_in_range(argp, op)) {
|
if (nfsd4_opnum_in_range(argp, op)) {
|
||||||
|
op->opdesc = OPDESC(op);
|
||||||
op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
|
op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
|
||||||
if (op->status != nfs_ok)
|
if (op->status != nfs_ok)
|
||||||
trace_nfsd_compound_decode_err(argp->rqstp,
|
trace_nfsd_compound_decode_err(argp->rqstp,
|
||||||
@ -2431,7 +2433,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
|||||||
op->opnum = OP_ILLEGAL;
|
op->opnum = OP_ILLEGAL;
|
||||||
op->status = nfserr_op_illegal;
|
op->status = nfserr_op_illegal;
|
||||||
}
|
}
|
||||||
op->opdesc = OPDESC(op);
|
|
||||||
/*
|
/*
|
||||||
* We'll try to cache the result in the DRC if any one
|
* We'll try to cache the result in the DRC if any one
|
||||||
* op in the compound wants to be cached:
|
* op in the compound wants to be cached:
|
||||||
|
Reference in New Issue
Block a user