提交 820c687b 编写于 作者: L Linus Torvalds

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
...@@ -78,6 +78,15 @@ ...@@ -78,6 +78,15 @@
#define VSD_FIRST_SECTOR_OFFSET 32768 #define VSD_FIRST_SECTOR_OFFSET 32768
#define VSD_MAX_SECTOR_OFFSET 0x800000 #define VSD_MAX_SECTOR_OFFSET 0x800000
/*
* Maximum number of Terminating Descriptor / Logical Volume Integrity
* Descriptor redirections. The chosen numbers are arbitrary - just that we
* hopefully don't limit any real use of rewritten inode on write-once media
* but avoid looping for too long on corrupted media.
*/
#define UDF_MAX_TD_NESTING 64
#define UDF_MAX_LVID_NESTING 1000
enum { UDF_MAX_LINKS = 0xffff }; enum { UDF_MAX_LINKS = 0xffff };
/* These are the "meat" - everything else is stuffing */ /* These are the "meat" - everything else is stuffing */
...@@ -1541,42 +1550,52 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, ...@@ -1541,42 +1550,52 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,
} }
/* /*
* udf_load_logicalvolint * Find the prevailing Logical Volume Integrity Descriptor.
*
*/ */
static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc) static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc)
{ {
struct buffer_head *bh = NULL; struct buffer_head *bh, *final_bh;
uint16_t ident; uint16_t ident;
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
struct logicalVolIntegrityDesc *lvid; struct logicalVolIntegrityDesc *lvid;
int indirections = 0;
while (++indirections <= UDF_MAX_LVID_NESTING) {
final_bh = NULL;
while (loc.extLength > 0 &&
(bh = udf_read_tagged(sb, loc.extLocation,
loc.extLocation, &ident))) {
if (ident != TAG_IDENT_LVID) {
brelse(bh);
break;
}
brelse(final_bh);
final_bh = bh;
while (loc.extLength > 0 && loc.extLength -= sb->s_blocksize;
(bh = udf_read_tagged(sb, loc.extLocation, loc.extLocation++;
loc.extLocation, &ident)) && }
ident == TAG_IDENT_LVID) {
sbi->s_lvid_bh = bh;
lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
if (lvid->nextIntegrityExt.extLength) if (!final_bh)
udf_load_logicalvolint(sb, return;
leea_to_cpu(lvid->nextIntegrityExt));
if (sbi->s_lvid_bh != bh) brelse(sbi->s_lvid_bh);
brelse(bh); sbi->s_lvid_bh = final_bh;
loc.extLength -= sb->s_blocksize;
loc.extLocation++; lvid = (struct logicalVolIntegrityDesc *)final_bh->b_data;
if (lvid->nextIntegrityExt.extLength == 0)
return;
loc = leea_to_cpu(lvid->nextIntegrityExt);
} }
if (sbi->s_lvid_bh != bh)
brelse(bh); udf_warn(sb, "Too many LVID indirections (max %u), ignoring.\n",
UDF_MAX_LVID_NESTING);
brelse(sbi->s_lvid_bh);
sbi->s_lvid_bh = NULL;
} }
/*
* Maximum number of Terminating Descriptor redirections. The chosen number is
* arbitrary - just that we hopefully don't limit any real use of rewritten
* inode on write-once media but avoid looping for too long on corrupted media.
*/
#define UDF_MAX_TD_NESTING 64
/* /*
* Process a main/reserve volume descriptor sequence. * Process a main/reserve volume descriptor sequence.
......
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/magic.h>
/* Since UDF 2.01 is ISO 13346 based... */
#define UDF_SUPER_MAGIC 0x15013346
#define UDF_MAX_READ_VERSION 0x0250 #define UDF_MAX_READ_VERSION 0x0250
#define UDF_MAX_WRITE_VERSION 0x0201 #define UDF_MAX_WRITE_VERSION 0x0201
......
...@@ -78,5 +78,7 @@ ...@@ -78,5 +78,7 @@
#define BTRFS_TEST_MAGIC 0x73727279 #define BTRFS_TEST_MAGIC 0x73727279
#define NSFS_MAGIC 0x6e736673 #define NSFS_MAGIC 0x6e736673
#define BPF_FS_MAGIC 0xcafe4a11 #define BPF_FS_MAGIC 0xcafe4a11
/* Since UDF 2.01 is ISO 13346 based... */
#define UDF_SUPER_MAGIC 0x15013346
#endif /* __LINUX_MAGIC_H__ */ #endif /* __LINUX_MAGIC_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册