Oops in register_chrdev, what did I do?
While experimenting a bit with a small kernel module, I got this oops. Digging further, I found that /proc/devices had an entry saying
248 <NULL>
which would indicate that I passed a NULL name to register_chrdev(), only I didn't. I used a string constant, so I can't see what changed it to NULL along the way.
What am I missing here?
Unable to handle kernel NULL pointer dereference at virtual address 00000000 c014cad4 *pde = 00000000 Oops: 0000 [#1] CPU: 0 EIP: 0060:[<c014cad4>] Tainted: P
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00210282 (2.6.6)
eax: e0f93414 ebx: e0f93410 ecx: 00000000 edx: 00000000
esi: 00000000 edi: e0f93414 ebp: de43357c esp: d7487f64
ds: 007b es: 007b ss: 0068
Stack: 00000000 e0f93414 fffffff4 000000f8 c0332c74 d7486000 e8969b80 d7487fa0
e896b023 000000f8 e89691c9 e8969b20 fffffffc c0332c74 d7486000 c0332c5c
c012ac2a 00000001 00000000 40152000 00000003 00000000 d7486000 c0103d29
Call Trace:
[<e896b023>] init_foo+0x23/0x40 [foo]
[<c012ac2a>] sys_init_module+0x105/0x211
[<c0103d29>] sysenter_past_esp+0x52/0x71
Code: ac aa 84 c0 75 fa ba 2f 00 00 00 8b 74 24 04 89 d0 88 c4 ac Quoted 7 lines
Quoted 7 lines
EIP;
c014cad4<register_chrdev+57/f8> <=====eax;
e0f93414<pg0+20ba9414/3fc14000>
ebx;e0f93410<pg0+20ba9410/3fc14000>
edi;e0f93414<pg0+20ba9414/3fc14000>
ebp;de43357c<pg0+1e04957c/3fc14000>
esp;d7487f64<pg0+1709df64/3fc14000>
Trace; e896b023 <pg0+28581023/3fc14000>
Trace; c012ac2a <sys_init_module+105/211>
Trace; c0103d29 <sysenter_past_esp+52/71>
Code; c014cad4 <register_chrdev+57/f8>
00000000 <_EIP>:
Code; c014cad4 <register_chrdev+57/f8> <=====
0: ac lods %ds:(%esi),%al <=====
Code; c014cad5 <register_chrdev+58/f8>
1: aa stos %al,%es:(%edi)
Code; c014cad6 <register_chrdev+59/f8>
2: 84 c0 test %al,%al
Code; c014cad8 <register_chrdev+5b/f8>
4: 75 fa jne 0 <_EIP>
Code; c014cada <register_chrdev+5d/f8>
6: ba 2f 00 00 00 mov $0x2f,%edx
Code; c014cadf <register_chrdev+62/f8>
b: 8b 74 24 04 mov 0x4(%esp,1),%esi
Code; c014cae3 <register_chrdev+66/f8>
f: 89 d0 mov %edx,%eax
Code; c014cae5 <register_chrdev+68/f8>
11: 88 c4 mov %al,%ah
Code; c014cae7 <register_chrdev+6a/f8>
13: ac lods %ds:(%esi),%al
Signature · 2 lines
Måns Rullgård [email protected]
Uttered Måns Rullgård <[email protected]>, spake thus:
Quoted 8 lines
While experimenting a bit with a small kernel module, I got this oops. Digging further, I found that
/proc/deviceshad an entry saying 248 <NULL>
which would indicate that I passed a NULL name toregister_chrdev(), only I didn't. I used a string constant, so I can't see what changed it to NULL along the way.What am I missing here?
Enough information for us to help you. Show us your code snippet, please.
Quoted 9 lines · Tommy Reynolds
Uttered Måns Rullgård <[email protected]>, spake thus:
Quoted 7 lines
While experimenting a bit with a small kernel module, I got this oops. Digging further, I found that
/proc/deviceshad an entry saying 248 <NULL>
which would indicate that I passed a NULL name toregister_chrdev(), only I didn't. I used a string constant, so I can't see what changed it to NULL along the way.
Quoted 4 lines
Quoted 1 line
What am I missing here?
Enough information for us to help you. Show us your code snippet, please.
I can't imagine that the details of the fops functions are a problem, since they never get called.
static struct file_operations foo_fops = {
.owner = THIS_MODULE,
.open = foo_open,
.read = foo_read,
.write = foo_write,
.mmap = foo_mmap, .release = foo_release
};
static int __initinit_foo(void)
{
int err;
err = register_chrdev(foo_major, "foo", &foo_fops);
if(err)
return err;
return 0;
}static void __exitexit_foo(void)
{
unregister_chrdev(foo_major, "foo");
}module_init(init_foo);module_exit(exit_foo);MODULE_LICENSE("GPL");
Signature · 2 lines
Måns Rullgård [email protected]
Quoted 10 lines · Måns Rullgård
While experimenting a bit with a small kernel module, I got this oops. Digging further, I found that
/proc/deviceshad an entry saying248 <NULL>
which would indicate that I passed a NULL name to
register_chrdev(), only I didn't. I used a string constant, so I can't see what changed it to NULL along the way.What am I missing here?
There was some confusion with compiler versions and flags, most notably -mregparm. Fixed now. Sorry for the noise.
OTOH, wouldn't it be a good idea to refuse loading modules not matching the running kernel?
Signature · 2 lines
Måns Rullgård [email protected]
Quoted 3 lines
OTOH, wouldn't it be a good idea to refuse loading modules not matching the running kernel?
we do that already... provided you use the kbuild infrastructure instead of a broken self-made makefile hack....
Quoted 5 lines · Arjan van de Ven
Quoted 2 lines
OTOH, wouldn't it be a good idea to refuse loading modules not matching the running kernel?
we do that already... provided you use the kbuild infrastructure instead of a broken self-made makefile hack....
I used "make -C /lib/modules/uname -r SUBDIRS=$PWD modules". Is that not correct? The breakage was my fault, though.
The problem I see is that a modules contain information about certain compiler flags used, e.g. -mregparm, but insmod still attempts to load them even they do not match the kernel. This is independent of what build system you used.
Signature · 2 lines
Måns Rullgård [email protected]
Quoted 10 lines · Måns Rullgård
Quoted 5 lines · Arjan van de Ven
Quoted 2 lines
OTOH, wouldn't it be a good idea to refuse loading modules not matching the running kernel?
we do that already... provided you use the kbuild infrastructure instead of a broken self-made makefile hack....
I used "make -C
/lib/modules/uname -rSUBDIRS=$PWD modules". Is that not correct? The breakage was my fault, though.
that is correct
Quoted 5 lines
The problem I see is that a modules contain information about certain compiler flags used, e.g. -mregparm, but insmod still attempts to load them even they do not match the kernel. This is independent of what build system you used.
that is odd, which modutils is that ? Afaik insmod is supposed to just refuse (and I've seen it do that as well)
Quoted 7 lines · Arjan van de Ven
Quoted 4 lines
The problem I see is that a modules contain information about certain compiler flags used, e.g. -mregparm, but insmod still attempts to load them even they do not match the kernel. This is independent of what build system you used.
that is odd, which modutils is that ? Afaik insmod is supposed to just refuse (and I've seen it do that as well)
A little embarrassing perhaps, but it was quite old. I'm upgrading to 3.0.
Signature · 2 lines
Måns Rullgård [email protected]