isofs: handle CDs with bad root inode but good Joliet root directory

[ Upstream commit 4243bf80c7 ]

I have a CD copy of the original Tom Clancy's Ghost Recon game from
2001. The disc mounts without error on Windows, but on Linux mounting
fails with the message "isofs_fill_super: get root inode failed". The
error originates in isofs_read_inode, which returns -EIO because de_len
is 0. The superblock on this disc appears to be intentionally corrupt as
a form of copy protection.

When the root inode is unusable, instead of giving up immediately, try
to continue with the Joliet file table. This fixes the Ghost Recon CD
and probably other copy-protected CDs too.

Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Message-Id: <20240208022134.451490-1-alexhenrie24@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Alex Henrie 2024-02-07 19:21:32 -07:00 committed by Greg Kroah-Hartman
parent ee0b5f96b6
commit 13701b0f01

View File

@ -908,8 +908,22 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
* we then decide whether to use the Joliet descriptor.
*/
inode = isofs_iget(s, sbi->s_firstdatazone, 0);
if (IS_ERR(inode))
goto out_no_root;
/*
* Fix for broken CDs with a corrupt root inode but a correct Joliet
* root directory.
*/
if (IS_ERR(inode)) {
if (joliet_level && sbi->s_firstdatazone != first_data_zone) {
printk(KERN_NOTICE
"ISOFS: root inode is unusable. "
"Disabling Rock Ridge and switching to Joliet.");
sbi->s_rock = 0;
inode = NULL;
} else {
goto out_no_root;
}
}
/*
* Fix for broken CDs with Rock Ridge and empty ISO root directory but