Commit 85d71244f02583886dc20a60df2d4657d42116b4
Committed by
Linus Torvalds
1 parent
296baae254
Exists in
master
and in
4 other branches
Fix possible UDF data corruption
update_next_aext() could possibly rewrite values in elen and eloc, possibly leading to data corruption when rewriting a file. Use temporary variables instead. Also advance cur_epos as it can also point to an indirect extent pointer. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 8 additions and 4 deletions Side-by-side Diff
fs/udf/inode.c
... | ... | @@ -460,8 +460,8 @@ |
460 | 460 | kernel_long_ad laarr[EXTENT_MERGE_SIZE]; |
461 | 461 | struct extent_position prev_epos, cur_epos, next_epos; |
462 | 462 | int count = 0, startnum = 0, endnum = 0; |
463 | - uint32_t elen = 0; | |
464 | - kernel_lb_addr eloc; | |
463 | + uint32_t elen = 0, tmpelen; | |
464 | + kernel_lb_addr eloc, tmpeloc; | |
465 | 465 | int c = 1; |
466 | 466 | loff_t lbcount = 0, b_off = 0; |
467 | 467 | uint32_t newblocknum, newblock; |
... | ... | @@ -520,8 +520,12 @@ |
520 | 520 | |
521 | 521 | b_off -= lbcount; |
522 | 522 | offset = b_off >> inode->i_sb->s_blocksize_bits; |
523 | - /* Move into indirect extent if we are at a pointer to it */ | |
524 | - udf_next_aext(inode, &prev_epos, &eloc, &elen, 0); | |
523 | + /* | |
524 | + * Move prev_epos and cur_epos into indirect extent if we are at | |
525 | + * the pointer to it | |
526 | + */ | |
527 | + udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0); | |
528 | + udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0); | |
525 | 529 | |
526 | 530 | /* if the extent is allocated and recorded, return the block |
527 | 531 | if the extent is not a multiple of the blocksize, round up */ |