From e4c83c5c17b19d3ad599b48a1cfabd5f90275594 Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Fri, 30 Mar 2012 19:41:17 +0100 Subject: [PATCH] afs: Handle reading past the end of a file ... except that this change doesn't actually handle this, it just stops clang from throwing an error about the bogus code that's already in there. This needs fixed properly ... Reviewed-on: http://gerrit.openafs.org/7090 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 3198cef8ccf0d9cb9a7479c0b973e604e21e62fc) This change differs slightly from the one on master because on master, afs_MemRead and afs_UFSRead were consolidated into afs_read(). On the 1.6 branch, we must patch the two functions separately. Change-Id: I7d8d104c89355c0a3294372340af0e02ab170b59 Reviewed-on: http://gerrit.openafs.org/10744 Tested-by: BuildBot Reviewed-by: Andrew Deason Reviewed-by: D Brashear Reviewed-by: Stephan Wiesand --- src/afs/VNOPS/afs_vnop_read.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/afs/VNOPS/afs_vnop_read.c b/src/afs/VNOPS/afs_vnop_read.c index acd02bfbd..4bef4d167 100644 --- a/src/afs/VNOPS/afs_vnop_read.c +++ b/src/afs/VNOPS/afs_vnop_read.c @@ -49,7 +49,8 @@ afs_MemRead(struct vcache *avc, struct uio *auio, afs_size_t totalLength; afs_size_t transferLength; afs_size_t filePos; - afs_size_t offset, len, tlen; + afs_size_t offset, tlen; + afs_size_t len = 0; afs_int32 trimlen; struct dcache *tdc = 0; afs_int32 error, trybusy = 1; @@ -110,6 +111,16 @@ afs_MemRead(struct vcache *avc, struct uio *auio, * Locks held: * avc->lock(R) */ + + /* This bit is bogus. We're checking to see if the read goes past the + * end of the file. If so, we should be zeroing out all of the buffers + * that the client has passed into us (there is a danger that we may leak + * kernel memory if we do not). However, this behaviour is disabled by + * not setting len before this segment runs, and by setting len to 0 + * immediately we enter it. In addition, we also need to check for a read + * which partially goes off the end of the file in the while loop below. + */ + if (filePos >= avc->f.m.Length) { if (len > AFS_ZEROS) len = sizeof(afs_zeros); /* and in 0 buffer */ @@ -493,7 +504,8 @@ afs_UFSRead(struct vcache *avc, struct uio *auio, afs_size_t totalLength; afs_size_t transferLength; afs_size_t filePos; - afs_size_t offset, len, tlen; + afs_size_t offset, tlen; + afs_size_t len = 0; afs_int32 trimlen; struct dcache *tdc = 0; afs_int32 error; @@ -560,6 +572,15 @@ afs_UFSRead(struct vcache *avc, struct uio *auio, } #endif + /* This bit is bogus. We're checking to see if the read goes past the + * end of the file. If so, we should be zeroing out all of the buffers + * that the client has passed into us (there is a danger that we may leak + * kernel memory if we do not). However, this behaviour is disabled by + * not setting len before this segment runs, and by setting len to 0 + * immediately we enter it. In addition, we also need to check for a read + * which partially goes off the end of the file in the while loop below. + */ + if (filePos >= avc->f.m.Length) { if (len > AFS_ZEROS) len = sizeof(afs_zeros); /* and in 0 buffer */ -- 2.39.5