Commit d8e8fbec authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'nfsd-6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux

Pull nfsd fixes from Chuck Lever:

 - Address three recently introduced regressions

* tag 'nfsd-6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
  NFSD: CREATE_SESSION must never cache NFS4ERR_DELAY replies
  SUNRPC: Revert 561141dd
  nfsd: Fix error cleanup path in nfsd_rename()
parents 50108c35 99dc2ef0
...@@ -3831,15 +3831,20 @@ nfsd4_create_session(struct svc_rqst *rqstp, ...@@ -3831,15 +3831,20 @@ nfsd4_create_session(struct svc_rqst *rqstp,
else else
cs_slot = &unconf->cl_cs_slot; cs_slot = &unconf->cl_cs_slot;
status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
if (status) { switch (status) {
if (status == nfserr_replay_cache) { case nfs_ok:
status = nfsd4_replay_create_session(cr_ses, cs_slot); cs_slot->sl_seqid++;
goto out_free_conn; cr_ses->seqid = cs_slot->sl_seqid;
} break;
case nfserr_replay_cache:
status = nfsd4_replay_create_session(cr_ses, cs_slot);
fallthrough;
case nfserr_jukebox:
/* The server MUST NOT cache NFS4ERR_DELAY */
goto out_free_conn;
default:
goto out_cache_error; goto out_cache_error;
} }
cs_slot->sl_seqid++;
cr_ses->seqid = cs_slot->sl_seqid;
/* RFC 8881 Section 18.36.4 Phase 3: Client ID confirmation. */ /* RFC 8881 Section 18.36.4 Phase 3: Client ID confirmation. */
if (conf) { if (conf) {
...@@ -3859,10 +3864,8 @@ nfsd4_create_session(struct svc_rqst *rqstp, ...@@ -3859,10 +3864,8 @@ nfsd4_create_session(struct svc_rqst *rqstp,
old = find_confirmed_client_by_name(&unconf->cl_name, nn); old = find_confirmed_client_by_name(&unconf->cl_name, nn);
if (old) { if (old) {
status = mark_client_expired_locked(old); status = mark_client_expired_locked(old);
if (status) { if (status)
old = NULL; goto out_expired_error;
goto out_cache_error;
}
trace_nfsd_clid_replaced(&old->cl_clientid); trace_nfsd_clid_replaced(&old->cl_clientid);
} }
move_to_confirmed(unconf); move_to_confirmed(unconf);
...@@ -3894,6 +3897,17 @@ nfsd4_create_session(struct svc_rqst *rqstp, ...@@ -3894,6 +3897,17 @@ nfsd4_create_session(struct svc_rqst *rqstp,
expire_client(old); expire_client(old);
return status; return status;
out_expired_error:
old = NULL;
/*
* Revert the slot seq_nr change so the server will process
* the client's resend instead of returning a cached response.
*/
if (status == nfserr_jukebox) {
cs_slot->sl_seqid--;
cr_ses->seqid = cs_slot->sl_seqid;
goto out_free_conn;
}
out_cache_error: out_cache_error:
nfsd4_cache_create_session(cr_ses, cs_slot, status); nfsd4_cache_create_session(cr_ses, cs_slot, status);
out_free_conn: out_free_conn:
......
...@@ -1852,7 +1852,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, ...@@ -1852,7 +1852,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
trap = lock_rename(tdentry, fdentry); trap = lock_rename(tdentry, fdentry);
if (IS_ERR(trap)) { if (IS_ERR(trap)) {
err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev;
goto out; goto out_want_write;
} }
err = fh_fill_pre_attrs(ffhp); err = fh_fill_pre_attrs(ffhp);
if (err != nfs_ok) if (err != nfs_ok)
...@@ -1922,6 +1922,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, ...@@ -1922,6 +1922,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
} }
out_unlock: out_unlock:
unlock_rename(tdentry, fdentry); unlock_rename(tdentry, fdentry);
out_want_write:
fh_drop_write(ffhp); fh_drop_write(ffhp);
/* /*
......
...@@ -921,8 +921,6 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, ...@@ -921,8 +921,6 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len,
* Caller provides the truncation length of the output token (h) in * Caller provides the truncation length of the output token (h) in
* cksumout.len. * cksumout.len.
* *
* Note that for RPCSEC, the "initial cipher state" is always all zeroes.
*
* Return values: * Return values:
* %GSS_S_COMPLETE: Digest computed, @cksumout filled in * %GSS_S_COMPLETE: Digest computed, @cksumout filled in
* %GSS_S_FAILURE: Call failed * %GSS_S_FAILURE: Call failed
...@@ -933,19 +931,22 @@ u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher, ...@@ -933,19 +931,22 @@ u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher,
int body_offset, struct xdr_netobj *cksumout) int body_offset, struct xdr_netobj *cksumout)
{ {
unsigned int ivsize = crypto_sync_skcipher_ivsize(cipher); unsigned int ivsize = crypto_sync_skcipher_ivsize(cipher);
static const u8 iv[GSS_KRB5_MAX_BLOCKSIZE];
struct ahash_request *req; struct ahash_request *req;
struct scatterlist sg[1]; struct scatterlist sg[1];
u8 *iv, *checksumdata;
int err = -ENOMEM; int err = -ENOMEM;
u8 *checksumdata;
checksumdata = kmalloc(crypto_ahash_digestsize(tfm), GFP_KERNEL); checksumdata = kmalloc(crypto_ahash_digestsize(tfm), GFP_KERNEL);
if (!checksumdata) if (!checksumdata)
return GSS_S_FAILURE; return GSS_S_FAILURE;
/* For RPCSEC, the "initial cipher state" is always all zeroes. */
iv = kzalloc(ivsize, GFP_KERNEL);
if (!iv)
goto out_free_mem;
req = ahash_request_alloc(tfm, GFP_KERNEL); req = ahash_request_alloc(tfm, GFP_KERNEL);
if (!req) if (!req)
goto out_free_cksumdata; goto out_free_mem;
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
err = crypto_ahash_init(req); err = crypto_ahash_init(req);
if (err) if (err)
...@@ -969,7 +970,8 @@ u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher, ...@@ -969,7 +970,8 @@ u32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher,
out_free_ahash: out_free_ahash:
ahash_request_free(req); ahash_request_free(req);
out_free_cksumdata: out_free_mem:
kfree(iv);
kfree_sensitive(checksumdata); kfree_sensitive(checksumdata);
return err ? GSS_S_FAILURE : GSS_S_COMPLETE; return err ? GSS_S_FAILURE : GSS_S_COMPLETE;
} }
......
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