Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression: system doesn't start if no DVD drive is connected #17

Open
RattletraPM opened this issue Jul 12, 2018 · 2 comments
Open

Regression: system doesn't start if no DVD drive is connected #17

RattletraPM opened this issue Jul 12, 2018 · 2 comments
Labels

Comments

@RattletraPM
Copy link

(I have opened a separate issue because it's unrelated from the previous one I've opened)

I've noticed that the OS won't start properly if no DVD drive is connected. This happens in MINI mode and seems to be a regression since mikep4, as that kernel is able to boot even with no DVD drive at all. mikep5 and DeltaResero's kernels seem to be affected aswell. I haven't tested any of the newer kernels in IOS mode, but mikep5 started up fine under IOS, which makes me think it's indeed related to the rvl-di module.

As for what happens, after booting via Gumboot the Tux logo shows up, but that's about it. Nothing happens, init doesn't seem to run at all. With older, non-gumboot kernels you'd just get a black screen. Connecting even just a DVD logic board will fix the issue, and the OS will boot just fine. This seems to happen on multiple Wii consoles and motherboards.

@neagix
Copy link
Owner

neagix commented Apr 12, 2019

@RattletraPM it is a kernel bug and it was already there in DeltaResero's version.

Thanks for clarifying out the exact way it affects the system.

I am not sure how this could be fixed though? It requires some kernel patch?

@neagix neagix added the bug label Apr 12, 2019
@RattletraPM
Copy link
Author

RattletraPM commented Apr 29, 2019

I've done a few more tests since making this issue and found a dirty fix.

The issue is indeed caused by the rvl-di driver, however trying to blacklist it simply wouldn't work. I tried both adding it to /etc/modprobe.d/blacklist and via the kernel parameter module_blacklist=, yet it would still get loaded and hang the system at boot.

Being the lazy person I am, I didn't want to mess with the source code and recompile the whole kernel, but before giving up I had an idea. What I thought about doing was to open the kernel's zImage in a hexeditor, find the device tree, find the string hollywood-di (offset 0x1B191) and change it to something else so it wouldn't be found at boot, and thus it would get ignored. I told you it was a dirty fix but hey, it worked!

So, I don't know how helpful this would be to make a proper fix, unlike mine, but at least there is a way to make Linux boot without a DVD drive for now. Most likely, giving an option to boot without DVD support via Gumboot would be enough if you don't want to touch the driver's source, so considering I know this is a niche issue, I'd say it could be an okay fix.

ThatsItForTheOtherOne pushed a commit to Wii-Linux/wii-linux-ngx that referenced this issue Oct 16, 2023
[ Upstream commit 67d7d8a ]

Hulk Robot reported a issue:
==================================================================
BUG: KASAN: use-after-free in ext4_xattr_set_entry+0x18ab/0x3500
Write of size 4105 at addr ffff8881675ef5f4 by task syz-executor.0/7092

CPU: 1 PID: 7092 Comm: syz-executor.0 Not tainted 4.19.90-dirty neagix#17
Call Trace:
[...]
 memcpy+0x34/0x50 mm/kasan/kasan.c:303
 ext4_xattr_set_entry+0x18ab/0x3500 fs/ext4/xattr.c:1747
 ext4_xattr_ibody_inline_set+0x86/0x2a0 fs/ext4/xattr.c:2205
 ext4_xattr_set_handle+0x940/0x1300 fs/ext4/xattr.c:2386
 ext4_xattr_set+0x1da/0x300 fs/ext4/xattr.c:2498
 __vfs_setxattr+0x112/0x170 fs/xattr.c:149
 __vfs_setxattr_noperm+0x11b/0x2a0 fs/xattr.c:180
 __vfs_setxattr_locked+0x17b/0x250 fs/xattr.c:238
 vfs_setxattr+0xed/0x270 fs/xattr.c:255
 setxattr+0x235/0x330 fs/xattr.c:520
 path_setxattr+0x176/0x190 fs/xattr.c:539
 __do_sys_lsetxattr fs/xattr.c:561 [inline]
 __se_sys_lsetxattr fs/xattr.c:557 [inline]
 __x64_sys_lsetxattr+0xc2/0x160 fs/xattr.c:557
 do_syscall_64+0xdf/0x530 arch/x86/entry/common.c:298
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x459fe9
RSP: 002b:00007fa5e54b4c08 EFLAGS: 00000246 ORIG_RAX: 00000000000000bd
RAX: ffffffffffffffda RBX: 000000000051bf60 RCX: 0000000000459fe9
RDX: 00000000200003c0 RSI: 0000000020000180 RDI: 0000000020000140
RBP: 000000000051bf60 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000001009 R11: 0000000000000246 R12: 0000000000000000
R13: 00007ffc73c93fc0 R14: 000000000051bf60 R15: 00007fa5e54b4d80
[...]
==================================================================

Above issue may happen as follows:
-------------------------------------
ext4_xattr_set
  ext4_xattr_set_handle
    ext4_xattr_ibody_find
      >> s->end < s->base
      >> no EXT4_STATE_XATTR
      >> xattr_check_inode is not executed
    ext4_xattr_ibody_set
      ext4_xattr_set_entry
       >> size_t min_offs = s->end - s->base
       >> UAF in memcpy

we can easily reproduce this problem with the following commands:
    mkfs.ext4 -F /dev/sda
    mount -o debug_want_extra_isize=128 /dev/sda /mnt
    touch /mnt/file
    setfattr -n user.cat -v `seq -s z 4096|tr -d '[:digit:]'` /mnt/file

In ext4_xattr_ibody_find, we have the following assignment logic:
  header = IHDR(inode, raw_inode)
         = raw_inode + EXT4_GOOD_OLD_INODE_SIZE + i_extra_isize
  is->s.base = IFIRST(header)
             = header + sizeof(struct ext4_xattr_ibody_header)
  is->s.end = raw_inode + s_inode_size

In ext4_xattr_set_entry
  min_offs = s->end - s->base
           = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
	     sizeof(struct ext4_xattr_ibody_header)
  last = s->first
  free = min_offs - ((void *)last - s->base) - sizeof(__u32)
       = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
         sizeof(struct ext4_xattr_ibody_header) - sizeof(__u32)

In the calculation formula, all values except s_inode_size and
i_extra_size are fixed values. When i_extra_size is the maximum value
s_inode_size - EXT4_GOOD_OLD_INODE_SIZE, min_offs is -4 and free is -8.
The value overflows. As a result, the preceding issue is triggered when
memcpy is executed.

Therefore, when finding xattr or setting xattr, check whether
there is space for storing xattr in the inode to resolve this issue.

Cc: [email protected]
Reported-by: Hulk Robot <[email protected]>
Signed-off-by: Baokun Li <[email protected]>
Reviewed-by: Ritesh Harjani (IBM) <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Tudor Ambarus <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
[uli: backport to 4.4]
Signed-off-by: Ulrich Hecht <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants