Commit 221ef8e7 authored by Trond Myklebust's avatar Trond Myklebust

RPC: Improved buffer overrun checking in call_verify

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@fys.uio.no>
parent 12020a68
...@@ -967,8 +967,12 @@ call_header(struct rpc_task *task) ...@@ -967,8 +967,12 @@ call_header(struct rpc_task *task)
static u32 * static u32 *
call_verify(struct rpc_task *task) call_verify(struct rpc_task *task)
{ {
u32 *p = task->tk_rqstp->rq_rcv_buf.head[0].iov_base, n; struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0];
int len = task->tk_rqstp->rq_rcv_buf.len >> 2;
u32 *p = iov->iov_base, n;
if ((len -= 3) < 0)
goto garbage;
p += 1; /* skip XID */ p += 1; /* skip XID */
if ((n = ntohl(*p++)) != RPC_REPLY) { if ((n = ntohl(*p++)) != RPC_REPLY) {
...@@ -978,9 +982,11 @@ call_verify(struct rpc_task *task) ...@@ -978,9 +982,11 @@ call_verify(struct rpc_task *task)
if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) { if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
int error = -EACCES; int error = -EACCES;
if (--len < 0)
goto garbage;
if ((n = ntohl(*p++)) != RPC_AUTH_ERROR) { if ((n = ntohl(*p++)) != RPC_AUTH_ERROR) {
printk(KERN_WARNING "call_verify: RPC call rejected: %x\n", n); printk(KERN_WARNING "call_verify: RPC call rejected: %x\n", n);
} else } else if (--len < 0)
switch ((n = ntohl(*p++))) { switch ((n = ntohl(*p++))) {
case RPC_AUTH_REJECTEDCRED: case RPC_AUTH_REJECTEDCRED:
case RPC_AUTH_REJECTEDVERF: case RPC_AUTH_REJECTEDVERF:
...@@ -1011,7 +1017,8 @@ call_verify(struct rpc_task *task) ...@@ -1011,7 +1017,8 @@ call_verify(struct rpc_task *task)
default: default:
printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n); printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n);
error = -EIO; error = -EIO;
} } else
goto garbage;
dprintk("RPC: %4d call_verify: call rejected %d\n", dprintk("RPC: %4d call_verify: call rejected %d\n",
task->tk_pid, n); task->tk_pid, n);
rpc_exit(task, error); rpc_exit(task, error);
...@@ -1021,6 +1028,9 @@ call_verify(struct rpc_task *task) ...@@ -1021,6 +1028,9 @@ call_verify(struct rpc_task *task)
printk(KERN_WARNING "call_verify: auth check failed\n"); printk(KERN_WARNING "call_verify: auth check failed\n");
goto garbage; /* bad verifier, retry */ goto garbage; /* bad verifier, retry */
} }
len = p - (u32 *)iov->iov_base - 1;
if (len < 0)
goto garbage;
switch ((n = ntohl(*p++))) { switch ((n = ntohl(*p++))) {
case RPC_SUCCESS: case RPC_SUCCESS:
return p; return p;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment