mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 15:43:08 -04:00
isofs: Drop support of directory entries straddling blocks
Based on isofs standard (ECMA-119) directory entries are not allowed to straddle sector boundaries. Isofs images I have available seem to follow this. Now that we have code verifying validity of directory entries (and so we'd properly refuse such entries), let's just drop the code merging directory entries straddling sector boundaries. Acked-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
@@ -84,7 +84,7 @@ int get_acorn_filename(struct iso_directory_record *de,
|
||||
*/
|
||||
static int do_isofs_readdir(struct inode *inode, struct file *file,
|
||||
struct dir_context *ctx,
|
||||
char *tmpname, struct iso_directory_record *tmpde)
|
||||
char *tmpname)
|
||||
{
|
||||
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
|
||||
unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
|
||||
@@ -133,24 +133,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *file,
|
||||
offset_saved = offset;
|
||||
offset += de_len;
|
||||
|
||||
/* Make sure we have a full directory entry */
|
||||
if (offset >= bufsize) {
|
||||
int slop = bufsize - offset + de_len;
|
||||
memcpy(tmpde, de, slop);
|
||||
offset &= bufsize - 1;
|
||||
block++;
|
||||
brelse(bh);
|
||||
bh = NULL;
|
||||
if (offset) {
|
||||
bh = isofs_bread(inode, block);
|
||||
if (!bh)
|
||||
return 0;
|
||||
memcpy((void *) tmpde + slop, bh->b_data, offset);
|
||||
}
|
||||
de = tmpde;
|
||||
}
|
||||
if (!isofs_dir_record_valid(de, de == tmpde ? 0 : offset_saved,
|
||||
de == tmpde ? de_len : bufsize)) {
|
||||
if (!isofs_dir_record_valid(de, offset_saved, bufsize)) {
|
||||
printk(KERN_NOTICE "iso9660: Corrupted directory entry"
|
||||
" in block %lu of inode %llu\n", block,
|
||||
inode->i_ino);
|
||||
@@ -252,16 +235,13 @@ static int isofs_readdir(struct file *file, struct dir_context *ctx)
|
||||
{
|
||||
int result;
|
||||
char *tmpname;
|
||||
struct iso_directory_record *tmpde;
|
||||
struct inode *inode = file_inode(file);
|
||||
|
||||
tmpname = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
tmpname = kmalloc(1024, GFP_KERNEL);
|
||||
if (tmpname == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
tmpde = (struct iso_directory_record *) (tmpname+1024);
|
||||
|
||||
result = do_isofs_readdir(inode, file, ctx, tmpname, tmpde);
|
||||
result = do_isofs_readdir(inode, file, ctx, tmpname);
|
||||
|
||||
kfree(tmpname);
|
||||
return result;
|
||||
|
||||
@@ -48,7 +48,7 @@ isofs_cmp(struct dentry *dentry, const char *compare, int dlen)
|
||||
static unsigned long
|
||||
isofs_find_entry(struct inode *dir, struct dentry *dentry,
|
||||
unsigned long *block_rv, unsigned long *offset_rv,
|
||||
char *tmpname, struct iso_directory_record *tmpde)
|
||||
char *tmpname)
|
||||
{
|
||||
unsigned long bufsize = ISOFS_BUFFER_SIZE(dir);
|
||||
unsigned char bufbits = ISOFS_BUFFER_BITS(dir);
|
||||
@@ -91,25 +91,7 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
|
||||
offset += de_len;
|
||||
f_pos += de_len;
|
||||
|
||||
/* Make sure we have a full directory entry */
|
||||
if (offset >= bufsize) {
|
||||
int slop = bufsize - offset + de_len;
|
||||
memcpy(tmpde, de, slop);
|
||||
offset &= bufsize - 1;
|
||||
block++;
|
||||
brelse(bh);
|
||||
bh = NULL;
|
||||
if (offset) {
|
||||
bh = isofs_bread(dir, block);
|
||||
if (!bh)
|
||||
return 0;
|
||||
memcpy((void *) tmpde + slop, bh->b_data, offset);
|
||||
}
|
||||
de = tmpde;
|
||||
}
|
||||
|
||||
if (!isofs_dir_record_valid(de, de == tmpde ? 0 : offset_saved,
|
||||
de == tmpde ? de_len : bufsize)) {
|
||||
if (!isofs_dir_record_valid(de, offset_saved, bufsize)) {
|
||||
printk(KERN_NOTICE "iso9660: Corrupted directory entry"
|
||||
" in block %lu of inode %llu\n", block,
|
||||
dir->i_ino);
|
||||
@@ -169,17 +151,14 @@ struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, unsigned i
|
||||
unsigned long block;
|
||||
unsigned long offset;
|
||||
struct inode *inode;
|
||||
struct page *page;
|
||||
char *tmpname;
|
||||
|
||||
page = alloc_page(GFP_USER);
|
||||
if (!page)
|
||||
tmpname = kmalloc(1024, GFP_USER);
|
||||
if (!tmpname)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
found = isofs_find_entry(dir, dentry,
|
||||
&block, &offset,
|
||||
page_address(page),
|
||||
1024 + page_address(page));
|
||||
__free_page(page);
|
||||
found = isofs_find_entry(dir, dentry, &block, &offset, tmpname);
|
||||
kfree(tmpname);
|
||||
|
||||
inode = found ? isofs_iget(dir->i_sb, block, offset) : NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user