aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-17 17:25:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-17 17:25:02 -0400
commit820c687b70ae2c72972240b83c053cb7c85ddbc3 (patch)
tree8a144e528f287c3e05ba97a60ade45be91f6255c
parentdba1e987312ed318dfd46d4684e9e97b2223f2e8 (diff)
parent2a28900be20640fcd1e548b1e3bad79e8221fcf9 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull UDF fixes from Jan Kara: "A fix for UDF crash on corrupted media and one UDF header fixup" * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: udf: Export superblock magic to userspace udf: Prevent stack overflow on corrupted filesystem mount
-rw-r--r--fs/udf/super.c67
-rw-r--r--fs/udf/udf_sb.h4
-rw-r--r--include/uapi/linux/magic.h2
3 files changed, 46 insertions, 27 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.
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 1f32c7bd9f57..27b5335730c9 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -3,9 +3,7 @@
3 3
4#include <linux/mutex.h> 4#include <linux/mutex.h>
5#include <linux/bitops.h> 5#include <linux/bitops.h>
6 6#include <linux/magic.h>
7/* Since UDF 2.01 is ISO 13346 based... */
8#define UDF_SUPER_MAGIC 0x15013346
9 7
10#define UDF_MAX_READ_VERSION 0x0250 8#define UDF_MAX_READ_VERSION 0x0250
11#define UDF_MAX_WRITE_VERSION 0x0201 9#define UDF_MAX_WRITE_VERSION 0x0201
diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
index 0de181ad73d5..546b38886e11 100644
--- a/include/uapi/linux/magic.h
+++ b/include/uapi/linux/magic.h
@@ -78,5 +78,7 @@
78#define BTRFS_TEST_MAGIC 0x73727279 78#define BTRFS_TEST_MAGIC 0x73727279
79#define NSFS_MAGIC 0x6e736673 79#define NSFS_MAGIC 0x6e736673
80#define BPF_FS_MAGIC 0xcafe4a11 80#define BPF_FS_MAGIC 0xcafe4a11
81/* Since UDF 2.01 is ISO 13346 based... */
82#define UDF_SUPER_MAGIC 0x15013346
81 83
82#endif /* __LINUX_MAGIC_H__ */ 84#endif /* __LINUX_MAGIC_H__ */