Skip to content

Commit 6fa9041

Browse files
committed
Merge tag 'nfsd-6.18-3' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd fixes from Chuck Lever: "Address recently reported issues or issues found at the recent NFS bake-a-thon held in Raleigh, NC. Issues reported with v6.18-rc: - Address a kernel build issue - Reorder SEQUENCE processing to avoid spurious NFS4ERR_SEQ_MISORDERED Issues that need expedient stable backports: - Close a refcount leak exposure - Report support for NFSv4.2 CLONE correctly - Fix oops during COPY_NOTIFY processing - Prevent rare crash after XDR encoding failure - Prevent crash due to confused or malicious NFSv4.1 client" * tag 'nfsd-6.18-3' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: Revert "SUNRPC: Make RPCSEC_GSS_KRB5 select CRYPTO instead of depending on it" nfsd: ensure SEQUENCE replay sends a valid reply. NFSD: Never cache a COMPOUND when the SEQUENCE operation fails NFSD: Skip close replay processing if XDR encoding fails NFSD: free copynotify stateid in nfs4_free_ol_stateid() nfsd: add missing FATTR4_WORD2_CLONE_BLKSIZE from supported attributes nfsd: fix refcount leak in nfsd_set_fh_dentry()
2 parents 92385a0 + 324be6d commit 6fa9041

6 files changed

Lines changed: 58 additions & 28 deletions

File tree

fs/nfsd/nfs4state.c

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,7 +1542,8 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid)
15421542
release_all_access(stp);
15431543
if (stp->st_stateowner)
15441544
nfs4_put_stateowner(stp->st_stateowner);
1545-
WARN_ON(!list_empty(&stid->sc_cp_list));
1545+
if (!list_empty(&stid->sc_cp_list))
1546+
nfs4_free_cpntf_statelist(stid->sc_client->net, stid);
15461547
kmem_cache_free(stateid_slab, stid);
15471548
}
15481549

@@ -3486,7 +3487,20 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
34863487
struct nfsd4_slot *slot = resp->cstate.slot;
34873488
unsigned int base;
34883489

3489-
dprintk("--> %s slot %p\n", __func__, slot);
3490+
/*
3491+
* RFC 5661 Section 2.10.6.1.2:
3492+
*
3493+
* Any time SEQUENCE ... returns an error ... [t]he replier MUST NOT
3494+
* modify the reply cache entry for the slot whenever an error is
3495+
* returned from SEQUENCE ...
3496+
*
3497+
* Because nfsd4_store_cache_entry is called only by
3498+
* nfsd4_sequence_done(), nfsd4_store_cache_entry() is called only
3499+
* when a SEQUENCE operation was part of the COMPOUND.
3500+
* nfs41_check_op_ordering() ensures SEQUENCE is the first op.
3501+
*/
3502+
if (resp->opcnt == 1 && resp->cstate.status != nfs_ok)
3503+
return;
34903504

34913505
slot->sl_flags |= NFSD4_SLOT_INITIALIZED;
34923506
slot->sl_opcnt = resp->opcnt;
@@ -4349,6 +4363,36 @@ static bool replay_matches_cache(struct svc_rqst *rqstp,
43494363
return true;
43504364
}
43514365

4366+
/*
4367+
* Note that the response is constructed here both for the case
4368+
* of a new SEQUENCE request and for a replayed SEQUENCE request.
4369+
* We do not cache SEQUENCE responses as SEQUENCE is idempotent.
4370+
*/
4371+
static void nfsd4_construct_sequence_response(struct nfsd4_session *session,
4372+
struct nfsd4_sequence *seq)
4373+
{
4374+
struct nfs4_client *clp = session->se_client;
4375+
4376+
seq->maxslots_response = max(session->se_target_maxslots,
4377+
seq->maxslots);
4378+
seq->target_maxslots = session->se_target_maxslots;
4379+
4380+
switch (clp->cl_cb_state) {
4381+
case NFSD4_CB_DOWN:
4382+
seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN;
4383+
break;
4384+
case NFSD4_CB_FAULT:
4385+
seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT;
4386+
break;
4387+
default:
4388+
seq->status_flags = 0;
4389+
}
4390+
if (!list_empty(&clp->cl_revoked))
4391+
seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
4392+
if (atomic_read(&clp->cl_admin_revoked))
4393+
seq->status_flags |= SEQ4_STATUS_ADMIN_STATE_REVOKED;
4394+
}
4395+
43524396
__be32
43534397
nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
43544398
union nfsd4_op_u *u)
@@ -4398,6 +4442,9 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
43984442
dprintk("%s: slotid %d\n", __func__, seq->slotid);
43994443

44004444
trace_nfsd_slot_seqid_sequence(clp, seq, slot);
4445+
4446+
nfsd4_construct_sequence_response(session, seq);
4447+
44014448
status = check_slot_seqid(seq->seqid, slot->sl_seqid, slot->sl_flags);
44024449
if (status == nfserr_replay_cache) {
44034450
status = nfserr_seq_misordered;
@@ -4495,23 +4542,6 @@ nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
44954542
}
44964543

44974544
out:
4498-
seq->maxslots = max(session->se_target_maxslots, seq->maxslots);
4499-
seq->target_maxslots = session->se_target_maxslots;
4500-
4501-
switch (clp->cl_cb_state) {
4502-
case NFSD4_CB_DOWN:
4503-
seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN;
4504-
break;
4505-
case NFSD4_CB_FAULT:
4506-
seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT;
4507-
break;
4508-
default:
4509-
seq->status_flags = 0;
4510-
}
4511-
if (!list_empty(&clp->cl_revoked))
4512-
seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
4513-
if (atomic_read(&clp->cl_admin_revoked))
4514-
seq->status_flags |= SEQ4_STATUS_ADMIN_STATE_REVOKED;
45154545
trace_nfsd_seq4_status(rqstp, seq);
45164546
out_no_session:
45174547
if (conn)

fs/nfsd/nfs4xdr.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5073,7 +5073,7 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
50735073
return nfserr;
50745074
/* Note slotid's are numbered from zero: */
50755075
/* sr_highest_slotid */
5076-
nfserr = nfsd4_encode_slotid4(xdr, seq->maxslots - 1);
5076+
nfserr = nfsd4_encode_slotid4(xdr, seq->maxslots_response - 1);
50775077
if (nfserr != nfs_ok)
50785078
return nfserr;
50795079
/* sr_target_highest_slotid */
@@ -5925,8 +5925,7 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
59255925
*/
59265926
warn_on_nonidempotent_op(op);
59275927
xdr_truncate_encode(xdr, op_status_offset + XDR_UNIT);
5928-
}
5929-
if (so) {
5928+
} else if (so) {
59305929
int len = xdr->buf->len - (op_status_offset + XDR_UNIT);
59315930

59325931
so->so_replay.rp_status = op->status;

fs/nfsd/nfsd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ enum {
458458
#define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
459459
(NFSD4_1_SUPPORTED_ATTRS_WORD2 | \
460460
FATTR4_WORD2_MODE_UMASK | \
461+
FATTR4_WORD2_CLONE_BLKSIZE | \
461462
NFSD4_2_SECURITY_ATTRS | \
462463
FATTR4_WORD2_XATTR_SUPPORT | \
463464
FATTR4_WORD2_TIME_DELEG_ACCESS | \

fs/nfsd/nfsfh.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,6 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net,
269269
dentry);
270270
}
271271

272-
fhp->fh_dentry = dentry;
273-
fhp->fh_export = exp;
274-
275272
switch (fhp->fh_maxsize) {
276273
case NFS4_FHSIZE:
277274
if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOATOMIC_ATTR)
@@ -293,6 +290,9 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net,
293290
goto out;
294291
}
295292

293+
fhp->fh_dentry = dentry;
294+
fhp->fh_export = exp;
295+
296296
return 0;
297297
out:
298298
exp_put(exp);

fs/nfsd/xdr4.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,9 @@ struct nfsd4_sequence {
574574
struct nfs4_sessionid sessionid; /* request/response */
575575
u32 seqid; /* request/response */
576576
u32 slotid; /* request/response */
577-
u32 maxslots; /* request/response */
577+
u32 maxslots; /* request */
578578
u32 cachethis; /* request */
579+
u32 maxslots_response; /* response */
579580
u32 target_maxslots; /* response */
580581
u32 status_flags; /* response */
581582
};

net/sunrpc/Kconfig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ config SUNRPC_SWAP
1818

1919
config RPCSEC_GSS_KRB5
2020
tristate "Secure RPC: Kerberos V mechanism"
21-
depends on SUNRPC
21+
depends on SUNRPC && CRYPTO
2222
default y
2323
select SUNRPC_GSS
24-
select CRYPTO
2524
select CRYPTO_SKCIPHER
2625
select CRYPTO_HASH
2726
help

0 commit comments

Comments
 (0)