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:
Jan Kara
2026-07-28 17:59:53 +02:00
parent e2ee4078ec
commit b2eb2e2886
2 changed files with 11 additions and 52 deletions

View File

@@ -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;

View File

@@ -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;