Skip to content

Commit 47ee529

Browse files
author
J. Bruce Fields
committed
nfsd4: adjust buflen to session channel limit
We can simplify session limit enforcement by restricting the xdr buflen to the session size. Also fix a preexisting bug: we should really have been taking into account the auth-required space when comparing against session limits, which are limits on the size of the entire rpc reply, including any krb5 overhead. Signed-off-by: J. Bruce Fields <[email protected]>
1 parent db3f58a commit 47ee529

File tree

2 files changed

+19
-16
lines changed

2 files changed

+19
-16
lines changed

fs/nfsd/nfs4state.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2208,11 +2208,13 @@ nfsd4_sequence(struct svc_rqst *rqstp,
22082208
struct nfsd4_sequence *seq)
22092209
{
22102210
struct nfsd4_compoundres *resp = rqstp->rq_resp;
2211+
struct xdr_stream *xdr = &resp->xdr;
22112212
struct nfsd4_session *session;
22122213
struct nfs4_client *clp;
22132214
struct nfsd4_slot *slot;
22142215
struct nfsd4_conn *conn;
22152216
__be32 status;
2217+
int buflen;
22162218
struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
22172219

22182220
if (resp->opcnt != 1)
@@ -2281,6 +2283,15 @@ nfsd4_sequence(struct svc_rqst *rqstp,
22812283
if (status)
22822284
goto out_put_session;
22832285

2286+
buflen = (seq->cachethis) ?
2287+
session->se_fchannel.maxresp_cached :
2288+
session->se_fchannel.maxresp_sz;
2289+
status = (seq->cachethis) ? nfserr_rep_too_big_to_cache :
2290+
nfserr_rep_too_big;
2291+
if (xdr_restrict_buflen(xdr, buflen - 2 * RPC_MAX_AUTH_SIZE))
2292+
goto out_put_session;
2293+
2294+
status = nfs_ok;
22842295
/* Success! bump slot seqid */
22852296
slot->sl_seqid = seq->seqid;
22862297
slot->sl_flags |= NFSD4_SLOT_INUSE;

fs/nfsd/nfs4xdr.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3767,25 +3767,17 @@ static nfsd4_enc nfsd4_enc_ops[] = {
37673767
__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 respsize)
37683768
{
37693769
struct xdr_buf *buf = &resp->rqstp->rq_res;
3770-
struct nfsd4_session *session = resp->cstate.session;
3770+
struct nfsd4_slot *slot = resp->cstate.slot;
37713771

3772-
if (nfsd4_has_session(&resp->cstate)) {
3773-
struct nfsd4_slot *slot = resp->cstate.slot;
3774-
3775-
if (buf->len + respsize > session->se_fchannel.maxresp_sz)
3776-
return nfserr_rep_too_big;
3777-
3778-
if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) &&
3779-
buf->len + respsize > session->se_fchannel.maxresp_cached)
3780-
return nfserr_rep_too_big_to_cache;
3781-
}
3782-
3783-
if (buf->len + respsize > buf->buflen) {
3784-
WARN_ON_ONCE(nfsd4_has_session(&resp->cstate));
3772+
if (buf->len + respsize <= buf->buflen)
3773+
return nfs_ok;
3774+
if (!nfsd4_has_session(&resp->cstate))
37853775
return nfserr_resource;
3776+
if (slot->sl_flags & NFSD4_SLOT_CACHETHIS) {
3777+
WARN_ON_ONCE(1);
3778+
return nfserr_rep_too_big_to_cache;
37863779
}
3787-
3788-
return 0;
3780+
return nfserr_rep_too_big;
37893781
}
37903782

37913783
void

0 commit comments

Comments
 (0)