Commit ceeea1b7 authored by Linus Torvalds's avatar Linus Torvalds

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

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
...@@ -75,7 +75,6 @@ config NFS_V3_ACL ...@@ -75,7 +75,6 @@ config NFS_V3_ACL
config NFS_V4 config NFS_V4
tristate "NFS client support for NFS version 4" tristate "NFS client support for NFS version 4"
depends on NFS_FS depends on NFS_FS
select RPCSEC_GSS_KRB5
select KEYS select KEYS
help help
This option enables support for version 4 of the NFS protocol This option enables support for version 4 of the NFS protocol
......
...@@ -297,6 +297,7 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb, ...@@ -297,6 +297,7 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb,
out_free_dev: out_free_dev:
kfree(dev); kfree(dev);
gdp->gd_device = NULL;
return ret; return ret;
} }
......
...@@ -946,8 +946,8 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r ...@@ -946,8 +946,8 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r
if (!kcred) if (!kcred)
return NULL; return NULL;
kcred->uid = ses->se_cb_sec.uid; kcred->fsuid = ses->se_cb_sec.uid;
kcred->gid = ses->se_cb_sec.gid; kcred->fsgid = ses->se_cb_sec.gid;
return kcred; return kcred;
} }
} }
......
...@@ -2476,10 +2476,12 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) ...@@ -2476,10 +2476,12 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
for (i = 0; i < argp->opcnt; i++) { for (i = 0; i < argp->opcnt; i++) {
op = &argp->ops[i]; op = &argp->ops[i];
op->replay = NULL; op->replay = NULL;
op->opdesc = NULL;
if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0) if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
return false; return false;
if (nfsd4_opnum_in_range(argp, op)) { if (nfsd4_opnum_in_range(argp, op)) {
op->opdesc = OPDESC(op);
op->status = nfsd4_dec_ops[op->opnum](argp, &op->u); op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
if (op->status != nfs_ok) if (op->status != nfs_ok)
trace_nfsd_compound_decode_err(argp->rqstp, trace_nfsd_compound_decode_err(argp->rqstp,
...@@ -2490,7 +2492,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) ...@@ -2490,7 +2492,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
op->opnum = OP_ILLEGAL; op->opnum = OP_ILLEGAL;
op->status = nfserr_op_illegal; op->status = nfserr_op_illegal;
} }
op->opdesc = OPDESC(op);
/* /*
* We'll try to cache the result in the DRC if any one * We'll try to cache the result in the DRC if any one
* op in the compound wants to be cached: * op in the compound wants to be cached:
...@@ -5400,10 +5402,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) ...@@ -5400,10 +5402,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
__be32 *p; __be32 *p;
p = xdr_reserve_space(xdr, 8); p = xdr_reserve_space(xdr, 8);
if (!p) { if (!p)
WARN_ON_ONCE(1); goto release;
return;
}
*p++ = cpu_to_be32(op->opnum); *p++ = cpu_to_be32(op->opnum);
post_err_offset = xdr->buf->len; post_err_offset = xdr->buf->len;
...@@ -5418,8 +5418,6 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) ...@@ -5418,8 +5418,6 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
op->status = encoder(resp, op->status, &op->u); op->status = encoder(resp, op->status, &op->u);
if (op->status) if (op->status)
trace_nfsd_compound_encode_err(rqstp, op->opnum, 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); xdr_commit_encode(xdr);
/* nfsd4_check_resp_size guarantees enough room for error status */ /* 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) ...@@ -5460,6 +5458,9 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
} }
status: status:
*p = op->status; *p = op->status;
release:
if (opdesc && opdesc->op_release)
opdesc->op_release(&op->u);
} }
/* /*
......
...@@ -416,14 +416,23 @@ static int unix_gid_hash(kuid_t uid) ...@@ -416,14 +416,23 @@ static int unix_gid_hash(kuid_t uid)
return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS); 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(rcu, struct unix_gid, rcu);
struct unix_gid *ug = container_of(item, struct unix_gid, h); struct cache_head *item = &ug->h;
if (test_bit(CACHE_VALID, &item->flags) && if (test_bit(CACHE_VALID, &item->flags) &&
!test_bit(CACHE_NEGATIVE, &item->flags)) !test_bit(CACHE_NEGATIVE, &item->flags))
put_group_info(ug->gi); 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) static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
......
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