Commit 88fe73cb authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'nfsd-5.0-2' of git://linux-nfs.org/~bfields/linux

Pull more nfsd fixes from Bruce Fields:
 "Two small fixes, one for crashes using nfs/krb5 with older enctypes,
  one that could prevent clients from reclaiming state after a kernel
  upgrade"

* tag 'nfsd-5.0-2' of git://linux-nfs.org/~bfields/linux:
  sunrpc: fix 4 more call sites that were using stack memory with a scatterlist
  Revert "nfsd4: return default lease period"
parents 55638c52 e7afe6c1
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -1239,8 +1239,8 @@ static __net_init int nfsd_init_net(struct net *net)
	retval = nfsd_idmap_init(net);
	retval = nfsd_idmap_init(net);
	if (retval)
	if (retval)
		goto out_idmap_error;
		goto out_idmap_error;
	nn->nfsd4_lease = 45;	/* default lease time */
	nn->nfsd4_lease = 90;	/* default lease time */
	nn->nfsd4_grace = 45;
	nn->nfsd4_grace = 90;
	nn->somebody_reclaimed = false;
	nn->somebody_reclaimed = false;
	nn->clverifier_counter = prandom_u32();
	nn->clverifier_counter = prandom_u32();
	nn->clientid_counter = prandom_u32();
	nn->clientid_counter = prandom_u32();
+38 −11
Original line number Original line Diff line number Diff line
@@ -44,7 +44,7 @@ krb5_make_rc4_seq_num(struct krb5_ctx *kctx, int direction, s32 seqnum,
		      unsigned char *cksum, unsigned char *buf)
		      unsigned char *cksum, unsigned char *buf)
{
{
	struct crypto_sync_skcipher *cipher;
	struct crypto_sync_skcipher *cipher;
	unsigned char plain[8];
	unsigned char *plain;
	s32 code;
	s32 code;


	dprintk("RPC:       %s:\n", __func__);
	dprintk("RPC:       %s:\n", __func__);
@@ -52,6 +52,10 @@ krb5_make_rc4_seq_num(struct krb5_ctx *kctx, int direction, s32 seqnum,
	if (IS_ERR(cipher))
	if (IS_ERR(cipher))
		return PTR_ERR(cipher);
		return PTR_ERR(cipher);


	plain = kmalloc(8, GFP_NOFS);
	if (!plain)
		return -ENOMEM;

	plain[0] = (unsigned char) ((seqnum >> 24) & 0xff);
	plain[0] = (unsigned char) ((seqnum >> 24) & 0xff);
	plain[1] = (unsigned char) ((seqnum >> 16) & 0xff);
	plain[1] = (unsigned char) ((seqnum >> 16) & 0xff);
	plain[2] = (unsigned char) ((seqnum >> 8) & 0xff);
	plain[2] = (unsigned char) ((seqnum >> 8) & 0xff);
@@ -67,6 +71,7 @@ krb5_make_rc4_seq_num(struct krb5_ctx *kctx, int direction, s32 seqnum,


	code = krb5_encrypt(cipher, cksum, plain, buf, 8);
	code = krb5_encrypt(cipher, cksum, plain, buf, 8);
out:
out:
	kfree(plain);
	crypto_free_sync_skcipher(cipher);
	crypto_free_sync_skcipher(cipher);
	return code;
	return code;
}
}
@@ -77,12 +82,17 @@ krb5_make_seq_num(struct krb5_ctx *kctx,
		u32 seqnum,
		u32 seqnum,
		unsigned char *cksum, unsigned char *buf)
		unsigned char *cksum, unsigned char *buf)
{
{
	unsigned char plain[8];
	unsigned char *plain;
	s32 code;


	if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)
	if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)
		return krb5_make_rc4_seq_num(kctx, direction, seqnum,
		return krb5_make_rc4_seq_num(kctx, direction, seqnum,
					     cksum, buf);
					     cksum, buf);


	plain = kmalloc(8, GFP_NOFS);
	if (!plain)
		return -ENOMEM;

	plain[0] = (unsigned char) (seqnum & 0xff);
	plain[0] = (unsigned char) (seqnum & 0xff);
	plain[1] = (unsigned char) ((seqnum >> 8) & 0xff);
	plain[1] = (unsigned char) ((seqnum >> 8) & 0xff);
	plain[2] = (unsigned char) ((seqnum >> 16) & 0xff);
	plain[2] = (unsigned char) ((seqnum >> 16) & 0xff);
@@ -93,7 +103,9 @@ krb5_make_seq_num(struct krb5_ctx *kctx,
	plain[6] = direction;
	plain[6] = direction;
	plain[7] = direction;
	plain[7] = direction;


	return krb5_encrypt(key, cksum, plain, buf, 8);
	code = krb5_encrypt(key, cksum, plain, buf, 8);
	kfree(plain);
	return code;
}
}


static s32
static s32
@@ -101,7 +113,7 @@ krb5_get_rc4_seq_num(struct krb5_ctx *kctx, unsigned char *cksum,
		     unsigned char *buf, int *direction, s32 *seqnum)
		     unsigned char *buf, int *direction, s32 *seqnum)
{
{
	struct crypto_sync_skcipher *cipher;
	struct crypto_sync_skcipher *cipher;
	unsigned char plain[8];
	unsigned char *plain;
	s32 code;
	s32 code;


	dprintk("RPC:       %s:\n", __func__);
	dprintk("RPC:       %s:\n", __func__);
@@ -113,20 +125,28 @@ krb5_get_rc4_seq_num(struct krb5_ctx *kctx, unsigned char *cksum,
	if (code)
	if (code)
		goto out;
		goto out;


	plain = kmalloc(8, GFP_NOFS);
	if (!plain) {
		code = -ENOMEM;
		goto out;
	}

	code = krb5_decrypt(cipher, cksum, buf, plain, 8);
	code = krb5_decrypt(cipher, cksum, buf, plain, 8);
	if (code)
	if (code)
		goto out;
		goto out_plain;


	if ((plain[4] != plain[5]) || (plain[4] != plain[6])
	if ((plain[4] != plain[5]) || (plain[4] != plain[6])
				   || (plain[4] != plain[7])) {
				   || (plain[4] != plain[7])) {
		code = (s32)KG_BAD_SEQ;
		code = (s32)KG_BAD_SEQ;
		goto out;
		goto out_plain;
	}
	}


	*direction = plain[4];
	*direction = plain[4];


	*seqnum = ((plain[0] << 24) | (plain[1] << 16) |
	*seqnum = ((plain[0] << 24) | (plain[1] << 16) |
					(plain[2] << 8) | (plain[3]));
					(plain[2] << 8) | (plain[3]));
out_plain:
	kfree(plain);
out:
out:
	crypto_free_sync_skcipher(cipher);
	crypto_free_sync_skcipher(cipher);
	return code;
	return code;
@@ -139,7 +159,7 @@ krb5_get_seq_num(struct krb5_ctx *kctx,
	       int *direction, u32 *seqnum)
	       int *direction, u32 *seqnum)
{
{
	s32 code;
	s32 code;
	unsigned char plain[8];
	unsigned char *plain;
	struct crypto_sync_skcipher *key = kctx->seq;
	struct crypto_sync_skcipher *key = kctx->seq;


	dprintk("RPC:       krb5_get_seq_num:\n");
	dprintk("RPC:       krb5_get_seq_num:\n");
@@ -147,18 +167,25 @@ krb5_get_seq_num(struct krb5_ctx *kctx,
	if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)
	if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)
		return krb5_get_rc4_seq_num(kctx, cksum, buf,
		return krb5_get_rc4_seq_num(kctx, cksum, buf,
					    direction, seqnum);
					    direction, seqnum);
	plain = kmalloc(8, GFP_NOFS);
	if (!plain)
		return -ENOMEM;


	if ((code = krb5_decrypt(key, cksum, buf, plain, 8)))
	if ((code = krb5_decrypt(key, cksum, buf, plain, 8)))
		return code;
		goto out;


	if ((plain[4] != plain[5]) || (plain[4] != plain[6]) ||
	if ((plain[4] != plain[5]) || (plain[4] != plain[6]) ||
	    (plain[4] != plain[7]))
	    (plain[4] != plain[7])) {
		return (s32)KG_BAD_SEQ;
		code = (s32)KG_BAD_SEQ;
		goto out;
	}


	*direction = plain[4];
	*direction = plain[4];


	*seqnum = ((plain[0]) |
	*seqnum = ((plain[0]) |
		   (plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24));
		   (plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24));


	return 0;
out:
	kfree(plain);
	return code;
}
}