diff options
Diffstat (limited to 'fs/udf/inode.c')
-rw-r--r-- | fs/udf/inode.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 5bc71d9a674a..a445d599098d 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -750,7 +750,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, | |||
750 | /* Are we beyond EOF? */ | 750 | /* Are we beyond EOF? */ |
751 | if (etype == -1) { | 751 | if (etype == -1) { |
752 | int ret; | 752 | int ret; |
753 | isBeyondEOF = 1; | 753 | isBeyondEOF = true; |
754 | if (count) { | 754 | if (count) { |
755 | if (c) | 755 | if (c) |
756 | laarr[0] = laarr[1]; | 756 | laarr[0] = laarr[1]; |
@@ -792,7 +792,7 @@ static sector_t inode_getblk(struct inode *inode, sector_t block, | |||
792 | endnum = c + 1; | 792 | endnum = c + 1; |
793 | lastblock = 1; | 793 | lastblock = 1; |
794 | } else { | 794 | } else { |
795 | isBeyondEOF = 0; | 795 | isBeyondEOF = false; |
796 | endnum = startnum = ((count > 2) ? 2 : count); | 796 | endnum = startnum = ((count > 2) ? 2 : count); |
797 | 797 | ||
798 | /* if the current extent is in position 0, | 798 | /* if the current extent is in position 0, |
@@ -1288,6 +1288,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode) | |||
1288 | struct kernel_lb_addr *iloc = &iinfo->i_location; | 1288 | struct kernel_lb_addr *iloc = &iinfo->i_location; |
1289 | unsigned int link_count; | 1289 | unsigned int link_count; |
1290 | unsigned int indirections = 0; | 1290 | unsigned int indirections = 0; |
1291 | int bs = inode->i_sb->s_blocksize; | ||
1291 | int ret = -EIO; | 1292 | int ret = -EIO; |
1292 | 1293 | ||
1293 | reread: | 1294 | reread: |
@@ -1374,38 +1375,35 @@ reread: | |||
1374 | if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) { | 1375 | if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) { |
1375 | iinfo->i_efe = 1; | 1376 | iinfo->i_efe = 1; |
1376 | iinfo->i_use = 0; | 1377 | iinfo->i_use = 0; |
1377 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - | 1378 | ret = udf_alloc_i_data(inode, bs - |
1378 | sizeof(struct extendedFileEntry)); | 1379 | sizeof(struct extendedFileEntry)); |
1379 | if (ret) | 1380 | if (ret) |
1380 | goto out; | 1381 | goto out; |
1381 | memcpy(iinfo->i_ext.i_data, | 1382 | memcpy(iinfo->i_ext.i_data, |
1382 | bh->b_data + sizeof(struct extendedFileEntry), | 1383 | bh->b_data + sizeof(struct extendedFileEntry), |
1383 | inode->i_sb->s_blocksize - | 1384 | bs - sizeof(struct extendedFileEntry)); |
1384 | sizeof(struct extendedFileEntry)); | ||
1385 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) { | 1385 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) { |
1386 | iinfo->i_efe = 0; | 1386 | iinfo->i_efe = 0; |
1387 | iinfo->i_use = 0; | 1387 | iinfo->i_use = 0; |
1388 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - | 1388 | ret = udf_alloc_i_data(inode, bs - sizeof(struct fileEntry)); |
1389 | sizeof(struct fileEntry)); | ||
1390 | if (ret) | 1389 | if (ret) |
1391 | goto out; | 1390 | goto out; |
1392 | memcpy(iinfo->i_ext.i_data, | 1391 | memcpy(iinfo->i_ext.i_data, |
1393 | bh->b_data + sizeof(struct fileEntry), | 1392 | bh->b_data + sizeof(struct fileEntry), |
1394 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); | 1393 | bs - sizeof(struct fileEntry)); |
1395 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { | 1394 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { |
1396 | iinfo->i_efe = 0; | 1395 | iinfo->i_efe = 0; |
1397 | iinfo->i_use = 1; | 1396 | iinfo->i_use = 1; |
1398 | iinfo->i_lenAlloc = le32_to_cpu( | 1397 | iinfo->i_lenAlloc = le32_to_cpu( |
1399 | ((struct unallocSpaceEntry *)bh->b_data)-> | 1398 | ((struct unallocSpaceEntry *)bh->b_data)-> |
1400 | lengthAllocDescs); | 1399 | lengthAllocDescs); |
1401 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - | 1400 | ret = udf_alloc_i_data(inode, bs - |
1402 | sizeof(struct unallocSpaceEntry)); | 1401 | sizeof(struct unallocSpaceEntry)); |
1403 | if (ret) | 1402 | if (ret) |
1404 | goto out; | 1403 | goto out; |
1405 | memcpy(iinfo->i_ext.i_data, | 1404 | memcpy(iinfo->i_ext.i_data, |
1406 | bh->b_data + sizeof(struct unallocSpaceEntry), | 1405 | bh->b_data + sizeof(struct unallocSpaceEntry), |
1407 | inode->i_sb->s_blocksize - | 1406 | bs - sizeof(struct unallocSpaceEntry)); |
1408 | sizeof(struct unallocSpaceEntry)); | ||
1409 | return 0; | 1407 | return 0; |
1410 | } | 1408 | } |
1411 | 1409 | ||
@@ -1489,6 +1487,15 @@ reread: | |||
1489 | } | 1487 | } |
1490 | inode->i_generation = iinfo->i_unique; | 1488 | inode->i_generation = iinfo->i_unique; |
1491 | 1489 | ||
1490 | /* | ||
1491 | * Sanity check length of allocation descriptors and extended attrs to | ||
1492 | * avoid integer overflows | ||
1493 | */ | ||
1494 | if (iinfo->i_lenEAttr > bs || iinfo->i_lenAlloc > bs) | ||
1495 | goto out; | ||
1496 | /* Now do exact checks */ | ||
1497 | if (udf_file_entry_alloc_offset(inode) + iinfo->i_lenAlloc > bs) | ||
1498 | goto out; | ||
1492 | /* Sanity checks for files in ICB so that we don't get confused later */ | 1499 | /* Sanity checks for files in ICB so that we don't get confused later */ |
1493 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1500 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1494 | /* | 1501 | /* |
@@ -1498,8 +1505,7 @@ reread: | |||
1498 | if (iinfo->i_lenAlloc != inode->i_size) | 1505 | if (iinfo->i_lenAlloc != inode->i_size) |
1499 | goto out; | 1506 | goto out; |
1500 | /* File in ICB has to fit in there... */ | 1507 | /* File in ICB has to fit in there... */ |
1501 | if (inode->i_size > inode->i_sb->s_blocksize - | 1508 | if (inode->i_size > bs - udf_file_entry_alloc_offset(inode)) |
1502 | udf_file_entry_alloc_offset(inode)) | ||
1503 | goto out; | 1509 | goto out; |
1504 | } | 1510 | } |
1505 | 1511 | ||