Commit 1d7b24ff authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'nfs-for-3.12-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes (part 2) from Trond Myklebust:
 "Bugfixes:
   - Fix a few credential reference leaks resulting from the
     SP4_MACH_CRED NFSv4.1 state protection code.
   - Fix the SUNRPC bloatometer footprint: convert a 256K hashtable into
     the intended 64 byte structure.
   - Fix a long standing XDR issue with FREE_STATEID
   - Fix a potential WARN_ON spamming issue
   - Fix a missing dprintk() kuid conversion

  New features:
   - Enable the NFSv4.1 state protection support for the WRITE and
     COMMIT operations"

* tag 'nfs-for-3.12-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  SUNRPC: No, I did not intend to create a 256KiB hashtable
  sunrpc: Add missing kuids conversion for printing
  NFSv4.1: sp4_mach_cred: WARN_ON -> WARN_ON_ONCE
  NFSv4.1: sp4_mach_cred: no need to ref count creds
  NFSv4.1: fix SECINFO* use of put_rpccred
  NFSv4.1: sp4_mach_cred: ask for WRITE and COMMIT
  NFSv4.1 fix decode_free_stateid
parents 68f0d9d9 23c323af
...@@ -279,15 +279,15 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode, ...@@ -279,15 +279,15 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
if (test_bit(sp4_mode, &clp->cl_sp4_flags)) { if (test_bit(sp4_mode, &clp->cl_sp4_flags)) {
spin_lock(&clp->cl_lock); spin_lock(&clp->cl_lock);
if (clp->cl_machine_cred != NULL) if (clp->cl_machine_cred != NULL)
newcred = get_rpccred(clp->cl_machine_cred); /* don't call get_rpccred on the machine cred -
* a reference will be held for life of clp */
newcred = clp->cl_machine_cred;
spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock);
if (msg->rpc_cred)
put_rpccred(msg->rpc_cred);
msg->rpc_cred = newcred; msg->rpc_cred = newcred;
flavor = clp->cl_rpcclient->cl_auth->au_flavor; flavor = clp->cl_rpcclient->cl_auth->au_flavor;
WARN_ON(flavor != RPC_AUTH_GSS_KRB5I && WARN_ON_ONCE(flavor != RPC_AUTH_GSS_KRB5I &&
flavor != RPC_AUTH_GSS_KRB5P); flavor != RPC_AUTH_GSS_KRB5P);
*clntp = clp->cl_rpcclient; *clntp = clp->cl_rpcclient;
return true; return true;
......
...@@ -6001,10 +6001,12 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct ...@@ -6001,10 +6001,12 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
.rpc_resp = &res, .rpc_resp = &res,
}; };
struct rpc_clnt *clnt = NFS_SERVER(dir)->client; struct rpc_clnt *clnt = NFS_SERVER(dir)->client;
struct rpc_cred *cred = NULL;
if (use_integrity) { if (use_integrity) {
clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient; clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient;
msg.rpc_cred = nfs4_get_clid_cred(NFS_SERVER(dir)->nfs_client); cred = nfs4_get_clid_cred(NFS_SERVER(dir)->nfs_client);
msg.rpc_cred = cred;
} }
dprintk("NFS call secinfo %s\n", name->name); dprintk("NFS call secinfo %s\n", name->name);
...@@ -6016,8 +6018,8 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct ...@@ -6016,8 +6018,8 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
&res.seq_res, 0); &res.seq_res, 0);
dprintk("NFS reply secinfo: %d\n", status); dprintk("NFS reply secinfo: %d\n", status);
if (msg.rpc_cred) if (cred)
put_rpccred(msg.rpc_cred); put_rpccred(cred);
return status; return status;
} }
...@@ -6151,11 +6153,13 @@ static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = { ...@@ -6151,11 +6153,13 @@ static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
}, },
.allow.u.words = { .allow.u.words = {
[0] = 1 << (OP_CLOSE) | [0] = 1 << (OP_CLOSE) |
1 << (OP_LOCKU), 1 << (OP_LOCKU) |
1 << (OP_COMMIT),
[1] = 1 << (OP_SECINFO - 32) | [1] = 1 << (OP_SECINFO - 32) |
1 << (OP_SECINFO_NO_NAME - 32) | 1 << (OP_SECINFO_NO_NAME - 32) |
1 << (OP_TEST_STATEID - 32) | 1 << (OP_TEST_STATEID - 32) |
1 << (OP_FREE_STATEID - 32) 1 << (OP_FREE_STATEID - 32) |
1 << (OP_WRITE - 32)
} }
}; };
...@@ -7496,11 +7500,13 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle, ...@@ -7496,11 +7500,13 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_resp = &res, .rpc_resp = &res,
}; };
struct rpc_clnt *clnt = server->client; struct rpc_clnt *clnt = server->client;
struct rpc_cred *cred = NULL;
int status; int status;
if (use_integrity) { if (use_integrity) {
clnt = server->nfs_client->cl_rpcclient; clnt = server->nfs_client->cl_rpcclient;
msg.rpc_cred = nfs4_get_clid_cred(server->nfs_client); cred = nfs4_get_clid_cred(server->nfs_client);
msg.rpc_cred = cred;
} }
dprintk("--> %s\n", __func__); dprintk("--> %s\n", __func__);
...@@ -7508,8 +7514,8 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle, ...@@ -7508,8 +7514,8 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
&res.seq_res, 0); &res.seq_res, 0);
dprintk("<-- %s status=%d\n", __func__, status); dprintk("<-- %s status=%d\n", __func__, status);
if (msg.rpc_cred) if (cred)
put_rpccred(msg.rpc_cred); put_rpccred(cred);
return status; return status;
} }
......
...@@ -414,7 +414,7 @@ static int nfs4_stat_to_errno(int); ...@@ -414,7 +414,7 @@ static int nfs4_stat_to_errno(int);
#define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1) #define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1)
#define encode_free_stateid_maxsz (op_encode_hdr_maxsz + 1 + \ #define encode_free_stateid_maxsz (op_encode_hdr_maxsz + 1 + \
XDR_QUADLEN(NFS4_STATEID_SIZE)) XDR_QUADLEN(NFS4_STATEID_SIZE))
#define decode_free_stateid_maxsz (op_decode_hdr_maxsz + 1) #define decode_free_stateid_maxsz (op_decode_hdr_maxsz)
#else /* CONFIG_NFS_V4_1 */ #else /* CONFIG_NFS_V4_1 */
#define encode_sequence_maxsz 0 #define encode_sequence_maxsz 0
#define decode_sequence_maxsz 0 #define decode_sequence_maxsz 0
...@@ -5966,21 +5966,8 @@ static int decode_test_stateid(struct xdr_stream *xdr, ...@@ -5966,21 +5966,8 @@ static int decode_test_stateid(struct xdr_stream *xdr,
static int decode_free_stateid(struct xdr_stream *xdr, static int decode_free_stateid(struct xdr_stream *xdr,
struct nfs41_free_stateid_res *res) struct nfs41_free_stateid_res *res)
{ {
__be32 *p; res->status = decode_op_hdr(xdr, OP_FREE_STATEID);
int status;
status = decode_op_hdr(xdr, OP_FREE_STATEID);
if (status)
return status;
p = xdr_inline_decode(xdr, 4);
if (unlikely(!p))
goto out_overflow;
res->status = be32_to_cpup(p++);
return res->status; return res->status;
out_overflow:
print_overflow_msg(__func__, xdr);
return -EIO;
} }
#endif /* CONFIG_NFS_V4_1 */ #endif /* CONFIG_NFS_V4_1 */
......
...@@ -239,7 +239,7 @@ generic_key_timeout(struct rpc_auth *auth, struct rpc_cred *cred) ...@@ -239,7 +239,7 @@ generic_key_timeout(struct rpc_auth *auth, struct rpc_cred *cred)
if (test_and_clear_bit(RPC_CRED_KEY_EXPIRE_SOON, if (test_and_clear_bit(RPC_CRED_KEY_EXPIRE_SOON,
&acred->ac_flags)) &acred->ac_flags))
dprintk("RPC: UID %d Credential key reset\n", dprintk("RPC: UID %d Credential key reset\n",
tcred->cr_uid); from_kuid(&init_user_ns, tcred->cr_uid));
/* set up fasttrack for the normal case */ /* set up fasttrack for the normal case */
set_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags); set_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags);
} }
......
...@@ -75,7 +75,7 @@ static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO; ...@@ -75,7 +75,7 @@ static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO;
* using integrity (two 4-byte integers): */ * using integrity (two 4-byte integers): */
#define GSS_VERF_SLACK 100 #define GSS_VERF_SLACK 100
static DEFINE_HASHTABLE(gss_auth_hash_table, 16); static DEFINE_HASHTABLE(gss_auth_hash_table, 4);
static DEFINE_SPINLOCK(gss_auth_hash_lock); static DEFINE_SPINLOCK(gss_auth_hash_lock);
struct gss_pipe { struct gss_pipe {
......
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