diff options
author | Steve Magnani <steve.magnani@digidescorp.com> | 2017-10-12 08:48:40 -0500 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2017-10-17 11:56:45 +0200 |
commit | b490bdd630cc43a5725e76c7c23f8a7e55551145 (patch) | |
tree | 9ee95e0af7d247b2a8b282b2b5ed1a783465e9da /fs/udf/namei.c | |
parent | 503c3117d05c184b431e403cd05c463ac41370f0 (diff) | |
download | linux-b490bdd630cc43a5725e76c7c23f8a7e55551145.tar.bz2 |
udf: Fix 64-bit sign extension issues affecting blocks > 0x7FFFFFFF
Large (> 1 TiB) UDF filesystems appear subject to several problems when
mounted on 64-bit systems:
* readdir() can fail on a directory containing File Identifiers residing
above 0x7FFFFFFF. This manifests as a 'ls' command failing with EIO.
* FIBMAP on a file block located above 0x7FFFFFFF can return a negative
value. The low 32 bits are correct, but applications that don't mask the
high 32 bits of the result can perform incorrectly.
Per suggestion by Jan Kara, introduce a udf_pblk_t type for representation
of UDF block addresses. Ultimately, all driver functions that manipulate
UDF block addresses should use this type; for now, deployment is limited
to functions with actual or potential sign extension issues.
Changes to udf_readdir() and udf_block_map() address the issues noted
above; other changes address potential similar issues uncovered during
audit of the driver code.
Signed-off-by: Steven J. Magnani <steve@digidescorp.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/namei.c')
-rw-r--r-- | fs/udf/namei.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 885198dfd9f8..d3f18a6fbe40 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -164,7 +164,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, { struct fileIdentDesc *fi = NULL; loff_t f_pos; - int block, flen; + udf_pblk_t block; + int flen; unsigned char *fname = NULL, *copy_name = NULL; unsigned char *nameptr; uint8_t lfi; @@ -352,7 +353,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, int nfidlen; uint8_t lfi; uint16_t liu; - int block; + udf_pblk_t block; struct kernel_lb_addr eloc; uint32_t elen = 0; sector_t offset; @@ -749,7 +750,7 @@ static int empty_dir(struct inode *dir) struct udf_fileident_bh fibh; loff_t f_pos; loff_t size = udf_ext0_offset(dir) + dir->i_size; - int block; + udf_pblk_t block; struct kernel_lb_addr eloc; uint32_t elen; sector_t offset; @@ -913,7 +914,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, int eoffset, elen = 0; uint8_t *ea; int err; - int block; + udf_pblk_t block; unsigned char *name = NULL; int namelen; struct udf_inode_info *iinfo; |