Skip to content

Commit 97b78ae

Browse files
trondmyamschuma-ntap
authored andcommitted
SUNRPC: Ensure we respect the RPCSEC_GSS sequence number limit
According to RFC2203, the RPCSEC_GSS sequence numbers are bounded to an upper limit of MAXSEQ = 0x80000000. Ensure that we handle that correctly. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent e66721f commit 97b78ae

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

net/sunrpc/auth_gss/auth_gss.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,8 +1549,10 @@ gss_marshal(struct rpc_task *task, __be32 *p)
15491549
cred_len = p++;
15501550

15511551
spin_lock(&ctx->gc_seq_lock);
1552-
req->rq_seqno = ctx->gc_seq++;
1552+
req->rq_seqno = (ctx->gc_seq < MAXSEQ) ? ctx->gc_seq++ : MAXSEQ;
15531553
spin_unlock(&ctx->gc_seq_lock);
1554+
if (req->rq_seqno == MAXSEQ)
1555+
goto out_expired;
15541556

15551557
*p++ = htonl((u32) RPC_GSS_VERSION);
15561558
*p++ = htonl((u32) ctx->gc_proc);
@@ -1572,14 +1574,18 @@ gss_marshal(struct rpc_task *task, __be32 *p)
15721574
mic.data = (u8 *)(p + 1);
15731575
maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
15741576
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
1575-
clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1577+
goto out_expired;
15761578
} else if (maj_stat != 0) {
1577-
printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
1579+
pr_warn("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
1580+
task->tk_status = -EIO;
15781581
goto out_put_ctx;
15791582
}
15801583
p = xdr_encode_opaque(p, NULL, mic.len);
15811584
gss_put_ctx(ctx);
15821585
return p;
1586+
out_expired:
1587+
clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1588+
task->tk_status = -EKEYEXPIRED;
15831589
out_put_ctx:
15841590
gss_put_ctx(ctx);
15851591
return NULL;

net/sunrpc/clnt.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,11 +1741,8 @@ rpc_xdr_encode(struct rpc_task *task)
17411741
req->rq_rcvsize);
17421742

17431743
p = rpc_encode_header(task);
1744-
if (p == NULL) {
1745-
printk(KERN_INFO "RPC: couldn't encode RPC header, exit EIO\n");
1746-
rpc_exit(task, -EIO);
1744+
if (p == NULL)
17471745
return;
1748-
}
17491746

17501747
encode = task->tk_msg.rpc_proc->p_encode;
17511748
if (encode == NULL)
@@ -1770,10 +1767,17 @@ call_encode(struct rpc_task *task)
17701767
/* Did the encode result in an error condition? */
17711768
if (task->tk_status != 0) {
17721769
/* Was the error nonfatal? */
1773-
if (task->tk_status == -EAGAIN || task->tk_status == -ENOMEM)
1770+
switch (task->tk_status) {
1771+
case -EAGAIN:
1772+
case -ENOMEM:
17741773
rpc_delay(task, HZ >> 4);
1775-
else
1774+
break;
1775+
case -EKEYEXPIRED:
1776+
task->tk_action = call_refresh;
1777+
break;
1778+
default:
17761779
rpc_exit(task, task->tk_status);
1780+
}
17771781
return;
17781782
}
17791783

@@ -2335,7 +2339,8 @@ rpc_encode_header(struct rpc_task *task)
23352339
*p++ = htonl(clnt->cl_vers); /* program version */
23362340
*p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */
23372341
p = rpcauth_marshcred(task, p);
2338-
req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p);
2342+
if (p)
2343+
req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p);
23392344
return p;
23402345
}
23412346

0 commit comments

Comments
 (0)