landley / toybox

toybox
http://landley.net/toybox
BSD Zero Clause License
2.4k stars 335 forks source link

modprobe fails loading dependencies #351

Closed smokku closed 1 year ago

smokku commented 2 years ago

While trying to load a module, modprobe fails to load dependency modules:

# modprobe -v /lib/modules/5.16.11-zen-gfbc389882a61/kernel/drivers/gpu/drm/tiny/bochs.ko
queuing /lib/modules/5.16.11-zen-gfbc389882a61/kernel/drivers/gpu/drm/tiny/bochs.ko
probing by module name
go_prob'ing bochs
loaded kernel/drivers/gpu/drm/ttm/ttm.ko '(null)': Bad address
modprobe: can't load module ttm (kernel/drivers/gpu/drm/ttm/ttm.ko): Bad address

When I try to load the dependency module, it works fine:

# modprobe -v kernel/drivers/gpu/drm/ttm/ttm.ko
queuing kernel/drivers/gpu/drm/ttm/ttm.ko
probing by module name
go_prob'ing ttm
loaded kernel/drivers/gpu/drm/ttm/ttm.ko ' ': No error information

The difference is that the second attempt uses a string instead of NULL as options:

loaded kernel/drivers/gpu/drm/ttm/ttm.ko '(null)': Bad address
---
loaded kernel/drivers/gpu/drm/ttm/ttm.ko ' ': No error information

It looks like syscall(__NR_finit_module does not like NULL flags.

With the following patch modprobe works fine:

---
 toys/pending/modprobe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/toys/pending/modprobe.c b/toys/pending/modprobe.c
index 45f8ea21..8188efaa 100644
--- a/toys/pending/modprobe.c
+++ b/toys/pending/modprobe.c
@@ -350,7 +350,7 @@ static int rm_mod(char *modules)
 // of flags, and don't need to support loading from stdin.
 static int ins_mod(char *modules, char *flags)
 {
-  int fd = xopenro(modules), rc = syscall(__NR_finit_module, fd, flags, 0);
+  int fd = xopenro(modules), rc = syscall(__NR_finit_module, fd, flags ? flags : "", 0);

   xclose(fd);
   return rc;
-- 
2.36.1
# modprobe -v /lib/modules/5.16.11-zen-gfbc389882a61/kernel/drivers/gpu/drm/tiny/bochs.ko
queuing /lib/modules/5.16.11-zen-gfbc389882a61/kernel/drivers/gpu/drm/tiny/bochs.ko
probing by module name
go_prob'ing bochs
loaded kernel/drivers/gpu/drm/ttm/ttm.ko '(null)': No error information
loaded kernel/drivers/gpu/drm/drm_ttm_helper.ko '(null)': No error information
loaded kernel/drivers/gpu/drm/drm_vram_helper.ko '(null)': No error information
loaded kernel/drivers/gpu/drm/tiny/bochs.ko ' ': No error information
apprehensions commented 1 year ago

can reproduce, facing this when trying to load graphics drivers.

how has this not been fixed yet?

landley commented 1 year ago

Because the systems I build use static kernels, and Android has a daemon use a module loading library instead of doing it from the command line. I have a TODO item to add module support to scripts/mkroot.sh but haven't done it yet. (It's behind "get 'make tests' running under mkroot", which means running under toysh. I tend not to run questionable stuff as root on my development machine, so "set up test environment for this" was the todo item, and it got buried.)

Thanks for the poke, I'll bump the priority up on the todo list...

landley commented 1 year ago

Slightly different variant applied as commit 56d89e51ba9e

smokku commented 1 year ago

Slightly different variant applied

My first fix was done this way. But this is just a workaround at a call site and does not fix the real issue with the syscall.

Every other user of ins_mod() might be tripped by the same bug.

landley commented 1 year ago

There are no other users, it's a static function in a "pending" command.

https://github.com/landley/toybox/blob/master/toys/pending/README

https://landley.net/toybox/cleanup.html