aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@ghost.suse.cz>2008-05-06 12:26:17 -0400
committerJan Kara <jack@suse.cz>2008-05-07 03:49:52 -0400
commit9afadc4b1fd25337003832c9a4668f9bd42cdda9 (patch)
tree45f0ce3a176c3562ff308189ced71ebb6f0a1110
parent221e583a735fc5d879d83c2a76b8ee5afcbdf146 (diff)
udf: Fix memory corruption when fs mounted with noadinicb option
When UDF filesystem is mounted with noadinicb mount option, it happens that we extend an empty directory with a block. A code in udf_add_entry() didn't count with this possibility and used uninitialized data leading to memory and filesystem corruption. Add a check whether file already has some extents before operating on them. Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/udf/namei.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 47a6589e10b5..3d94bc1cfbaf 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -315,7 +315,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
315 uint16_t liu; 315 uint16_t liu;
316 int block; 316 int block;
317 kernel_lb_addr eloc; 317 kernel_lb_addr eloc;
318 uint32_t elen; 318 uint32_t elen = 0;
319 sector_t offset; 319 sector_t offset;
320 struct extent_position epos = {}; 320 struct extent_position epos = {};
321 struct udf_inode_info *dinfo; 321 struct udf_inode_info *dinfo;
@@ -406,7 +406,8 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
406 } 406 }
407 407
408add: 408add:
409 if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { 409 /* Is there any extent whose size we need to round up? */
410 if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) {
410 elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); 411 elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1);
411 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 412 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
412 epos.offset -= sizeof(short_ad); 413 epos.offset -= sizeof(short_ad);