summaryrefslogtreecommitdiffstats
path: root/fs/adfs/adfs.h
diff options
context:
space:
mode:
authorStuart Swales <stuart.swales.croftnuisk@gmail.com>2011-03-22 16:35:04 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-22 17:44:17 -0700
commit2f09719af705db56032ae480a2d9c32c2a3fcbd3 (patch)
tree20fc7dc5c6955a943e01e78cfcdf77d1ab3e6027 /fs/adfs/adfs.h
parent12da58b0c89e27617aaedde7dcf99a8690875e91 (diff)
downloadlinux-2f09719af705db56032ae480a2d9c32c2a3fcbd3.tar.gz
linux-2f09719af705db56032ae480a2d9c32c2a3fcbd3.tar.bz2
linux-2f09719af705db56032ae480a2d9c32c2a3fcbd3.zip
adfs: fix E+/F+ dir size > 2048 crashing kernel
Kernel crashes in fs/adfs module when accessing directories with a large number of objects on mounted Acorn ADFS E+/F+ format discs (or images) as the existing code writes off the end of the fixed array of struct buffer_head pointers. Additionally, each directory access that didn't crash would leak a buffer as nr_buffers was not adjusted correctly for E+/F+ discs (was always left as one less than required). The patch fixes this by allocating a dynamically-sized set of struct buffer_head pointers if necessary for the E+/F+ case (many directories still do in fact fit in 2048 bytes) and sets the correct nr_buffers so that all buffers are released. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=26072 Tested by tar'ing the contents of my RISC PC's E+ format 20Gb HDD which contains a number of large directories that previously crashed the kernel. Signed-off-by: Stuart Swales <stuart.swales.croftnuisk@gmail.com> Cc: Russell King <rmk@arm.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/adfs/adfs.h')
-rw-r--r--fs/adfs/adfs.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h
index 2ff622f6f547..58588ddb178c 100644
--- a/fs/adfs/adfs.h
+++ b/fs/adfs/adfs.h
@@ -79,6 +79,10 @@ struct adfs_dir {
int nr_buffers;
struct buffer_head *bh[4];
+
+ /* big directories need allocated buffers */
+ struct buffer_head **bh_fplus;
+
unsigned int pos;
unsigned int parent_id;