aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2012-03-02 17:14:31 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-06 10:32:48 -0500
commitcd93710e8d290711ba2e08e1d1a380013aad667d (patch)
tree28f1a04dabfa3eaa64b61ea4491654e9ba70d889 /fs/nfs/nfs4proc.c
parentab19b4813fdbdef8f9c8732d1f7a2a69ae78d00b (diff)
NFS: Fix nfs4_verifier memory alignment
Clean up due to code review. The nfs4_verifier's data field is not guaranteed to be u32-aligned. Casting an array of chars to a u32 * is considered generally hazardous. Fix this by using a __be32 array to generate a verifier's contents, and then byte-copy the contents into the verifier field. The contents of a verifier, for all intents and purposes, are opaque bytes. Only local code that generates a verifier need know the actual content and format. Everyone else compares the full byte array for exact equality. Also, sizeof(nfs4_verifer) is the size of the in-core verifier data structure, but NFS4_VERIFIER_SIZE is the number of octets in an XDR'd verifier. The two are not interchangeable, even if they happen to have the same value. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index e0e35288361c..1ec05222ccbc 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -836,13 +836,15 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
836 p->o_arg.dir_bitmask = server->cache_consistency_bitmask; 836 p->o_arg.dir_bitmask = server->cache_consistency_bitmask;
837 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 837 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
838 if (attrs != NULL && attrs->ia_valid != 0) { 838 if (attrs != NULL && attrs->ia_valid != 0) {
839 u32 *s; 839 __be32 verf[2];
840 840
841 p->o_arg.u.attrs = &p->attrs; 841 p->o_arg.u.attrs = &p->attrs;
842 memcpy(&p->attrs, attrs, sizeof(p->attrs)); 842 memcpy(&p->attrs, attrs, sizeof(p->attrs));
843 s = (u32 *) p->o_arg.u.verifier.data; 843
844 s[0] = jiffies; 844 verf[0] = jiffies;
845 s[1] = current->pid; 845 verf[1] = current->pid;
846 memcpy(p->o_arg.u.verifier.data, verf,
847 sizeof(p->o_arg.u.verifier.data));
846 } 848 }
847 p->c_arg.fh = &p->o_res.fh; 849 p->c_arg.fh = &p->o_res.fh;
848 p->c_arg.stateid = &p->o_res.stateid; 850 p->c_arg.stateid = &p->o_res.stateid;
@@ -3819,6 +3821,16 @@ wait_on_recovery:
3819 return -EAGAIN; 3821 return -EAGAIN;
3820} 3822}
3821 3823
3824static void nfs4_construct_boot_verifier(struct nfs_client *clp,
3825 nfs4_verifier *bootverf)
3826{
3827 __be32 verf[2];
3828
3829 verf[0] = htonl((u32)clp->cl_boot_time.tv_sec);
3830 verf[1] = htonl((u32)clp->cl_boot_time.tv_nsec);
3831 memcpy(bootverf->data, verf, sizeof(bootverf->data));
3832}
3833
3822int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, 3834int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
3823 unsigned short port, struct rpc_cred *cred, 3835 unsigned short port, struct rpc_cred *cred,
3824 struct nfs4_setclientid_res *res) 3836 struct nfs4_setclientid_res *res)
@@ -3835,13 +3847,10 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
3835 .rpc_resp = res, 3847 .rpc_resp = res,
3836 .rpc_cred = cred, 3848 .rpc_cred = cred,
3837 }; 3849 };
3838 __be32 *p;
3839 int loop = 0; 3850 int loop = 0;
3840 int status; 3851 int status;
3841 3852
3842 p = (__be32*)sc_verifier.data; 3853 nfs4_construct_boot_verifier(clp, &sc_verifier);
3843 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
3844 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
3845 3854
3846 for(;;) { 3855 for(;;) {
3847 rcu_read_lock(); 3856 rcu_read_lock();
@@ -4933,6 +4942,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4933{ 4942{
4934 nfs4_verifier verifier; 4943 nfs4_verifier verifier;
4935 struct nfs41_exchange_id_args args = { 4944 struct nfs41_exchange_id_args args = {
4945 .verifier = &verifier,
4936 .client = clp, 4946 .client = clp,
4937 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER, 4947 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER,
4938 }; 4948 };
@@ -4946,15 +4956,11 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4946 .rpc_resp = &res, 4956 .rpc_resp = &res,
4947 .rpc_cred = cred, 4957 .rpc_cred = cred,
4948 }; 4958 };
4949 __be32 *p;
4950 4959
4951 dprintk("--> %s\n", __func__); 4960 dprintk("--> %s\n", __func__);
4952 BUG_ON(clp == NULL); 4961 BUG_ON(clp == NULL);
4953 4962
4954 p = (u32 *)verifier.data; 4963 nfs4_construct_boot_verifier(clp, &verifier);
4955 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4956 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
4957 args.verifier = &verifier;
4958 4964
4959 args.id_len = scnprintf(args.id, sizeof(args.id), 4965 args.id_len = scnprintf(args.id, sizeof(args.id),
4960 "%s/%s.%s/%u", 4966 "%s/%s.%s/%u",