diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/udf/inode.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 68cc7b144c26..a6a40536ebf1 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1270,6 +1270,13 @@ update_time: | |||
1270 | return 0; | 1270 | return 0; |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | /* | ||
1274 | * Maximum length of linked list formed by ICB hierarchy. The chosen number is | ||
1275 | * arbitrary - just that we hopefully don't limit any real use of rewritten | ||
1276 | * inode on write-once media but avoid looping for too long on corrupted media. | ||
1277 | */ | ||
1278 | #define UDF_MAX_ICB_NESTING 1024 | ||
1279 | |||
1273 | static void __udf_read_inode(struct inode *inode) | 1280 | static void __udf_read_inode(struct inode *inode) |
1274 | { | 1281 | { |
1275 | struct buffer_head *bh = NULL; | 1282 | struct buffer_head *bh = NULL; |
@@ -1279,7 +1286,9 @@ static void __udf_read_inode(struct inode *inode) | |||
1279 | struct udf_inode_info *iinfo = UDF_I(inode); | 1286 | struct udf_inode_info *iinfo = UDF_I(inode); |
1280 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); | 1287 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); |
1281 | unsigned int link_count; | 1288 | unsigned int link_count; |
1289 | unsigned int indirections = 0; | ||
1282 | 1290 | ||
1291 | reread: | ||
1283 | /* | 1292 | /* |
1284 | * Set defaults, but the inode is still incomplete! | 1293 | * Set defaults, but the inode is still incomplete! |
1285 | * Note: get_new_inode() sets the following on a new inode: | 1294 | * Note: get_new_inode() sets the following on a new inode: |
@@ -1317,28 +1326,26 @@ static void __udf_read_inode(struct inode *inode) | |||
1317 | ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1, | 1326 | ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1, |
1318 | &ident); | 1327 | &ident); |
1319 | if (ident == TAG_IDENT_IE && ibh) { | 1328 | if (ident == TAG_IDENT_IE && ibh) { |
1320 | struct buffer_head *nbh = NULL; | ||
1321 | struct kernel_lb_addr loc; | 1329 | struct kernel_lb_addr loc; |
1322 | struct indirectEntry *ie; | 1330 | struct indirectEntry *ie; |
1323 | 1331 | ||
1324 | ie = (struct indirectEntry *)ibh->b_data; | 1332 | ie = (struct indirectEntry *)ibh->b_data; |
1325 | loc = lelb_to_cpu(ie->indirectICB.extLocation); | 1333 | loc = lelb_to_cpu(ie->indirectICB.extLocation); |
1326 | 1334 | ||
1327 | if (ie->indirectICB.extLength && | 1335 | if (ie->indirectICB.extLength) { |
1328 | (nbh = udf_read_ptagged(inode->i_sb, &loc, 0, | 1336 | brelse(bh); |
1329 | &ident))) { | 1337 | brelse(ibh); |
1330 | if (ident == TAG_IDENT_FE || | 1338 | memcpy(&iinfo->i_location, &loc, |
1331 | ident == TAG_IDENT_EFE) { | 1339 | sizeof(struct kernel_lb_addr)); |
1332 | memcpy(&iinfo->i_location, | 1340 | if (++indirections > UDF_MAX_ICB_NESTING) { |
1333 | &loc, | 1341 | udf_err(inode->i_sb, |
1334 | sizeof(struct kernel_lb_addr)); | 1342 | "too many ICBs in ICB hierarchy" |
1335 | brelse(bh); | 1343 | " (max %d supported)\n", |
1336 | brelse(ibh); | 1344 | UDF_MAX_ICB_NESTING); |
1337 | brelse(nbh); | 1345 | make_bad_inode(inode); |
1338 | __udf_read_inode(inode); | ||
1339 | return; | 1346 | return; |
1340 | } | 1347 | } |
1341 | brelse(nbh); | 1348 | goto reread; |
1342 | } | 1349 | } |
1343 | } | 1350 | } |
1344 | brelse(ibh); | 1351 | brelse(ibh); |