Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 820c687b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents dba1e987 2a28900b
Loading
Loading
Loading
Loading
+43 −24
Original line number Diff line number Diff line
@@ -78,6 +78,15 @@
#define VSD_FIRST_SECTOR_OFFSET		32768
#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 };

/* These are the "meat" - everything else is stuffing */
@@ -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)
{
	struct buffer_head *bh = NULL;
	struct buffer_head *bh, *final_bh;
	uint16_t ident;
	struct udf_sb_info *sbi = UDF_SB(sb);
	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)) &&
	       ident == TAG_IDENT_LVID) {
		sbi->s_lvid_bh = bh;
		lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
					loc.extLocation, &ident))) {
			if (ident != TAG_IDENT_LVID) {
				brelse(bh);
				break;
			}

		if (lvid->nextIntegrityExt.extLength)
			udf_load_logicalvolint(sb,
				leea_to_cpu(lvid->nextIntegrityExt));
			brelse(final_bh);
			final_bh = bh;

		if (sbi->s_lvid_bh != bh)
			brelse(bh);
			loc.extLength -= sb->s_blocksize;
			loc.extLocation++;
		}
	if (sbi->s_lvid_bh != bh)
		brelse(bh);

		if (!final_bh)
			return;

		brelse(sbi->s_lvid_bh);
		sbi->s_lvid_bh = final_bh;

		lvid = (struct logicalVolIntegrityDesc *)final_bh->b_data;
		if (lvid->nextIntegrityExt.extLength == 0)
			return;

		loc = leea_to_cpu(lvid->nextIntegrityExt);
	}

	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.
+1 −3
Original line number Diff line number Diff line
@@ -3,9 +3,7 @@

#include <linux/mutex.h>
#include <linux/bitops.h>

/* Since UDF 2.01 is ISO 13346 based... */
#define UDF_SUPER_MAGIC			0x15013346
#include <linux/magic.h>

#define UDF_MAX_READ_VERSION		0x0250
#define UDF_MAX_WRITE_VERSION		0x0201
+2 −0
Original line number Diff line number Diff line
@@ -78,5 +78,7 @@
#define BTRFS_TEST_MAGIC	0x73727279
#define NSFS_MAGIC		0x6e736673
#define BPF_FS_MAGIC		0xcafe4a11
/* Since UDF 2.01 is ISO 13346 based... */
#define UDF_SUPER_MAGIC		0x15013346

#endif /* __LINUX_MAGIC_H__ */