summaryrefslogtreecommitdiffstats
path: root/fs/udf/super.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-06-03 15:05:51 +0200
committerThomas Gleixner <tglx@linutronix.de>2016-06-03 15:05:51 +0200
commit2eec3707a33fbf1c2e0a88ffc9fc0e465c2a59fd (patch)
tree9e47763ecd38f0ddd29f07e1ce199680304449fa /fs/udf/super.c
parent59fa5860204ffc95128d60cba9f54f9740a42c7d (diff)
parent0de6b9979e2e10c79e5702d2d902cd7284d17689 (diff)
downloadtalos-op-linux-2eec3707a33fbf1c2e0a88ffc9fc0e465c2a59fd.tar.gz
talos-op-linux-2eec3707a33fbf1c2e0a88ffc9fc0e465c2a59fd.zip
Merge tag 'irqchip-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent
Merge irqchip updates from Marc Zyngier: - A number of embarassing buglets (GICv3, PIC32) - A more substential errata workaround for Cavium's GICv3 ITS (kept for post-rc1 due to its dependency on NUMA)
Diffstat (limited to 'fs/udf/super.c')
-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 @@
#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 @@ out_bh:
}
/*
- * 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))) {
+ if (ident != TAG_IDENT_LVID) {
+ brelse(bh);
+ break;
+ }
+
+ brelse(final_bh);
+ final_bh = bh;
- 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.extLength -= sb->s_blocksize;
+ loc.extLocation++;
+ }
- if (lvid->nextIntegrityExt.extLength)
- udf_load_logicalvolint(sb,
- leea_to_cpu(lvid->nextIntegrityExt));
+ if (!final_bh)
+ return;
- if (sbi->s_lvid_bh != bh)
- brelse(bh);
- loc.extLength -= sb->s_blocksize;
- loc.extLocation++;
+ 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);
}
- 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.
OpenPOWER on IntegriCloud