Commit ceeea1b7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull nfsd fixes from Chuck Lever:

 - Fix a crash and a resource leak in NFSv4 COMPOUND processing

 - Fix issues with AUTH_SYS credential handling

 - Try again to address an NFS/NFSD/SUNRPC build dependency regression

* tag 'nfsd-6.3-5' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
  NFSD: callback request does not use correct credential for AUTH_SYS
  NFS: Remove "select RPCSEC_GSS_KRB5
  sunrpc: only free unix grouplist after RCU settles
  nfsd: call op_release, even when op_func returns an error
  NFSD: Avoid calling OPDESC() with ops->opnum == OP_ILLEGAL
parents 148341f0 7de82c2f
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -75,7 +75,6 @@ config NFS_V3_ACL
config NFS_V4
	tristate "NFS client support for NFS version 4"
	depends on NFS_FS
	select RPCSEC_GSS_KRB5
	select KEYS
	help
	  This option enables support for version 4 of the NFS protocol
+1 −0
Original line number Diff line number Diff line
@@ -297,6 +297,7 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb,

out_free_dev:
	kfree(dev);
	gdp->gd_device = NULL;
	return ret;
}

+2 −2
Original line number Diff line number Diff line
@@ -946,8 +946,8 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r
		if (!kcred)
			return NULL;

		kcred->uid = ses->se_cb_sec.uid;
		kcred->gid = ses->se_cb_sec.gid;
		kcred->fsuid = ses->se_cb_sec.uid;
		kcred->fsgid = ses->se_cb_sec.gid;
		return kcred;
	}
}
+8 −7
Original line number Diff line number Diff line
@@ -2476,10 +2476,12 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
	for (i = 0; i < argp->opcnt; i++) {
		op = &argp->ops[i];
		op->replay = NULL;
		op->opdesc = NULL;

		if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
			return false;
		if (nfsd4_opnum_in_range(argp, op)) {
			op->opdesc = OPDESC(op);
			op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
			if (op->status != nfs_ok)
				trace_nfsd_compound_decode_err(argp->rqstp,
@@ -2490,7 +2492,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
			op->opnum = OP_ILLEGAL;
			op->status = nfserr_op_illegal;
		}
		op->opdesc = OPDESC(op);

		/*
		 * We'll try to cache the result in the DRC if any one
		 * op in the compound wants to be cached:
@@ -5400,10 +5402,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
	__be32 *p;

	p = xdr_reserve_space(xdr, 8);
	if (!p) {
		WARN_ON_ONCE(1);
		return;
	}
	if (!p)
		goto release;
	*p++ = cpu_to_be32(op->opnum);
	post_err_offset = xdr->buf->len;

@@ -5418,8 +5418,6 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
	op->status = encoder(resp, op->status, &op->u);
	if (op->status)
		trace_nfsd_compound_encode_err(rqstp, op->opnum, op->status);
	if (opdesc && opdesc->op_release)
		opdesc->op_release(&op->u);
	xdr_commit_encode(xdr);

	/* nfsd4_check_resp_size guarantees enough room for error status */
@@ -5460,6 +5458,9 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
	}
status:
	*p = op->status;
release:
	if (opdesc && opdesc->op_release)
		opdesc->op_release(&op->u);
}

/* 
+13 −4
Original line number Diff line number Diff line
@@ -416,14 +416,23 @@ static int unix_gid_hash(kuid_t uid)
	return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
}

static void unix_gid_put(struct kref *kref)
static void unix_gid_free(struct rcu_head *rcu)
{
	struct cache_head *item = container_of(kref, struct cache_head, ref);
	struct unix_gid *ug = container_of(item, struct unix_gid, h);
	struct unix_gid *ug = container_of(rcu, struct unix_gid, rcu);
	struct cache_head *item = &ug->h;

	if (test_bit(CACHE_VALID, &item->flags) &&
	    !test_bit(CACHE_NEGATIVE, &item->flags))
		put_group_info(ug->gi);
	kfree_rcu(ug, rcu);
	kfree(ug);
}

static void unix_gid_put(struct kref *kref)
{
	struct cache_head *item = container_of(kref, struct cache_head, ref);
	struct unix_gid *ug = container_of(item, struct unix_gid, h);

	call_rcu(&ug->rcu, unix_gid_free);
}

static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)