diff options
author | Christoph Hellwig <hch@infradead.org> | 2009-03-03 14:48:36 -0500 |
---|---|---|
committer | Felix Blyakher <felixb@sgi.com> | 2009-03-04 07:31:42 -0600 |
commit | e8fa6b483feebd23ded5eb01afd7a6e82b6078c6 (patch) | |
tree | 39bdbcae18f9199c09e62c44136dc4b67bf2284b /fs/xfs | |
parent | d4fc7cea5dda04ae1a6f36175ec1dd8ff088ed52 (diff) | |
download | linux-e8fa6b483feebd23ded5eb01afd7a6e82b6078c6.tar.gz linux-e8fa6b483feebd23ded5eb01afd7a6e82b6078c6.tar.bz2 linux-e8fa6b483feebd23ded5eb01afd7a6e82b6078c6.zip |
xfs: prevent kernel crash due to corrupted inode log format
Andras Korn reported an oops on log replay causes by a corrupted
xfs_inode_log_format_t passing a 0 size to kmem_zalloc. This patch handles
to small or too large numbers of log regions gracefully by rejecting the
log replay with a useful error message.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reported-by: Andras Korn <korn-sgi.com@chardonnay.math.bme.hu>
Reviewed-by: Eric Sandeen <sandeen@sandeen.net>
Signed-off-by: Felix Blyakher <felixb@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 504d540e0e2c..ceeba45e0224 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1455,10 +1455,19 @@ xlog_recover_add_to_trans( item = item->ri_prev; if (item->ri_total == 0) { /* first region to be added */ - item->ri_total = in_f->ilf_size; - ASSERT(item->ri_total <= XLOG_MAX_REGIONS_IN_ITEM); - item->ri_buf = kmem_zalloc((item->ri_total * - sizeof(xfs_log_iovec_t)), KM_SLEEP); + if (in_f->ilf_size == 0 || + in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { + xlog_warn( + "XFS: bad number of regions (%d) in inode log format", + in_f->ilf_size); + ASSERT(0); + return XFS_ERROR(EIO); + } + + item->ri_total = in_f->ilf_size; + item->ri_buf = + kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), + KM_SLEEP); } ASSERT(item->ri_total > item->ri_cnt); /* Description region is ri_buf[0] */ |