| From: Bryan Schumaker <bjschuma@netapp.com> |
| Date: Fri, 19 Apr 2013 16:09:38 -0400 |
| Subject: nfsd: Decode and send 64bit time values |
| |
| 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 | 19 +++++-------------- |
| 1 file changed, 5 insertions(+), 14 deletions(-) |
| |
| --- a/fs/nfsd/nfs4xdr.c |
| +++ b/fs/nfsd/nfs4xdr.c |
| @@ -360,10 +360,7 @@ nfsd4_decode_fattr(struct nfsd4_compound |
| 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_compound |
| 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) { |