nfsd: Decode and send 64bit time values
authorBryan Schumaker <bjschuma@netapp.com>
Fri, 19 Apr 2013 20:09:38 +0000 (16:09 -0400)
committerBen Hutchings <ben@decadent.org.uk>
Mon, 13 May 2013 14:02:24 +0000 (15:02 +0100)
commit bf8d909705e9d9bac31d9b8eac6734d2b51332a7 upstream.

The seconds field of an nfstime4 structure is 64bit, but we are assuming
that the first 32bits are zero-filled.  So if the client tries to set
atime to a value before the epoch (touch -t 196001010101), then the
server will save the wrong value on disk.

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
fs/nfsd/nfs4xdr.c

index 24afa96..ade5316 100644 (file)
@@ -360,10 +360,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                           all 32 bits of 'nseconds'. */
                        READ_BUF(12);
                        len += 12;
-                       READ32(dummy32);
-                       if (dummy32)
-                               return nfserr_inval;
-                       READ32(iattr->ia_atime.tv_sec);
+                       READ64(iattr->ia_atime.tv_sec);
                        READ32(iattr->ia_atime.tv_nsec);
                        if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
                                return nfserr_inval;
@@ -386,10 +383,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                           all 32 bits of 'nseconds'. */
                        READ_BUF(12);
                        len += 12;
-                       READ32(dummy32);
-                       if (dummy32)
-                               return nfserr_inval;
-                       READ32(iattr->ia_mtime.tv_sec);
+                       READ64(iattr->ia_mtime.tv_sec);
                        READ32(iattr->ia_mtime.tv_nsec);
                        if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
                                return nfserr_inval;
@@ -2374,8 +2368,7 @@ out_acl:
        if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
                if ((buflen -= 12) < 0)
                        goto out_resource;
-               WRITE32(0);
-               WRITE32(stat.atime.tv_sec);
+               WRITE64((s64)stat.atime.tv_sec);
                WRITE32(stat.atime.tv_nsec);
        }
        if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
@@ -2388,15 +2381,13 @@ out_acl:
        if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
                if ((buflen -= 12) < 0)
                        goto out_resource;
-               WRITE32(0);
-               WRITE32(stat.ctime.tv_sec);
+               WRITE64((s64)stat.ctime.tv_sec);
                WRITE32(stat.ctime.tv_nsec);
        }
        if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
                if ((buflen -= 12) < 0)
                        goto out_resource;
-               WRITE32(0);
-               WRITE32(stat.mtime.tv_sec);
+               WRITE64((s64)stat.mtime.tv_sec);
                WRITE32(stat.mtime.tv_nsec);
        }
        if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {