summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2026-07-28 17:59:53 +0200
committerJan Kara <jack@suse.cz>2026-07-29 11:18:57 +0200
commitb2eb2e28860423c428fcfdd8b2bc86915418042d (patch)
treed2d910b4322f382bcc9ff3b18f9d0d6f8e7a95ba
parente2ee4078ec58d97abcb720d566835ad0d107bc23 (diff)
downloadlinux-next-b2eb2e28860423c428fcfdd8b2bc86915418042d.tar.gz
linux-next-b2eb2e28860423c428fcfdd8b2bc86915418042d.zip
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>
-rw-r--r--fs/isofs/dir.c28
-rw-r--r--fs/isofs/namei.c35
2 files changed, 11 insertions, 52 deletions
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
index a96268c9ca41..c7ca7603e97a 100644
--- a/fs/isofs/dir.c
+++ b/fs/isofs/dir.c
@@ -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;
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index a161b28893d6..010682f5901a 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -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;