aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
diff options
context:
space:
mode:
authorAlden Tondettar <alden.tondettar@gmail.com>2016-04-25 22:27:56 -0400
committerJan Kara <jack@suse.cz>2016-04-26 02:25:07 -0400
commita47241cdeee2689ee7089ec95cadfcf66588fbdb (patch)
tree78565c734b29f102c1d1350f71aae947cda8593e /fs/udf
parentc26f6c61578852f679787d555e6d07804e1f5f14 (diff)
udf: Prevent stack overflow on corrupted filesystem mount
Presently, a corrupted or malicious UDF filesystem containing a very large number (or cycle) of Logical Volume Integrity Descriptor extent indirections may trigger a stack overflow and kernel panic in udf_load_logicalvolint() on mount. Replace the unnecessary recursion in udf_load_logicalvolint() with simple iteration. Set an arbitrary limit of 1000 indirections (which would have almost certainly overflowed the stack without this fix), and treat such cases as if there were no LVID. Signed-off-by: Alden Tondettar <alden.tondettar@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf')
-rw-r--r--fs/udf/super.c67
1 files changed, 43 insertions, 24 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 36661acaf33b..5e2c8c814e1b 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -78,6 +78,15 @@
78#define VSD_FIRST_SECTOR_OFFSET 32768 78#define VSD_FIRST_SECTOR_OFFSET 32768
79#define VSD_MAX_SECTOR_OFFSET 0x800000 79#define VSD_MAX_SECTOR_OFFSET 0x800000
80 80
81/*
82 * Maximum number of Terminating Descriptor / Logical Volume Integrity
83 * Descriptor redirections. The chosen numbers are arbitrary - just that we
84 * hopefully don't limit any real use of rewritten inode on write-once media
85 * but avoid looping for too long on corrupted media.
86 */
87#define UDF_MAX_TD_NESTING 64
88#define UDF_MAX_LVID_NESTING 1000
89
81enum { UDF_MAX_LINKS = 0xffff }; 90enum { UDF_MAX_LINKS = 0xffff };
82 91
83/* These are the "meat" - everything else is stuffing */ 92/* These are the "meat" - everything else is stuffing */
@@ -1541,42 +1550,52 @@ out_bh:
1541} 1550}
1542 1551
1543/* 1552/*
1544 * udf_load_logicalvolint 1553 * Find the prevailing Logical Volume Integrity Descriptor.
1545 *
1546 */ 1554 */
1547static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc) 1555static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc)
1548{ 1556{
1549 struct buffer_head *bh = NULL; 1557 struct buffer_head *bh, *final_bh;
1550 uint16_t ident; 1558 uint16_t ident;
1551 struct udf_sb_info *sbi = UDF_SB(sb); 1559 struct udf_sb_info *sbi = UDF_SB(sb);
1552 struct logicalVolIntegrityDesc *lvid; 1560 struct logicalVolIntegrityDesc *lvid;
1561 int indirections = 0;
1562
1563 while (++indirections <= UDF_MAX_LVID_NESTING) {
1564 final_bh = NULL;
1565 while (loc.extLength > 0 &&
1566 (bh = udf_read_tagged(sb, loc.extLocation,
1567 loc.extLocation, &ident))) {
1568 if (ident != TAG_IDENT_LVID) {
1569 brelse(bh);
1570 break;
1571 }
1572
1573 brelse(final_bh);
1574 final_bh = bh;
1553 1575
1554 while (loc.extLength > 0 && 1576 loc.extLength -= sb->s_blocksize;
1555 (bh = udf_read_tagged(sb, loc.extLocation, 1577 loc.extLocation++;
1556 loc.extLocation, &ident)) && 1578 }
1557 ident == TAG_IDENT_LVID) {
1558 sbi->s_lvid_bh = bh;
1559 lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
1560 1579
1561 if (lvid->nextIntegrityExt.extLength) 1580 if (!final_bh)
1562 udf_load_logicalvolint(sb, 1581 return;
1563 leea_to_cpu(lvid->nextIntegrityExt));
1564 1582
1565 if (sbi->s_lvid_bh != bh) 1583 brelse(sbi->s_lvid_bh);
1566 brelse(bh); 1584 sbi->s_lvid_bh = final_bh;
1567 loc.extLength -= sb->s_blocksize; 1585
1568 loc.extLocation++; 1586 lvid = (struct logicalVolIntegrityDesc *)final_bh->b_data;
1587 if (lvid->nextIntegrityExt.extLength == 0)
1588 return;
1589
1590 loc = leea_to_cpu(lvid->nextIntegrityExt);
1569 } 1591 }
1570 if (sbi->s_lvid_bh != bh) 1592
1571 brelse(bh); 1593 udf_warn(sb, "Too many LVID indirections (max %u), ignoring.\n",
1594 UDF_MAX_LVID_NESTING);
1595 brelse(sbi->s_lvid_bh);
1596 sbi->s_lvid_bh = NULL;
1572} 1597}
1573 1598
1574/*
1575 * Maximum number of Terminating Descriptor redirections. The chosen number is
1576 * arbitrary - just that we hopefully don't limit any real use of rewritten
1577 * inode on write-once media but avoid looping for too long on corrupted media.
1578 */
1579#define UDF_MAX_TD_NESTING 64
1580 1599
1581/* 1600/*
1582 * Process a main/reserve volume descriptor sequence. 1601 * Process a main/reserve volume descriptor sequence.