On my AMD64 system, madfuload segaults when trying to download the firmware to an M-Audio transit (ma006100.bin).
$: uname -a
Linux Xerxes 2.6.17.3 #1 Wed Nov 1 22:32:51 CET 2006 x86_64 GNU/Linux
$: lsusb
Bus 005 Device 007: ID 0763:2006 Midiman
Bus 005 Device 003: ID 046d:c408 Logitech, Inc. Marble Mouse (4-button)
Bus 003 Device 002: ID 041e:3f08 Creative Technology, Ltd
Following stuff happens (yes, I did specify the wrong device file on purpose):
#:~/maudio/madfuload-1.2# ./madfuload -l -n -D /proc/bus/usb/005/005 -f /lib/firmware/`uname -r`/maudio/m006100.bin
Segmentation fault
With GDB, I see that there is some problem in fatal() and subsequently print():
(gdb) run
Starting program: ~/maudio/madfuload-1.2/madfuload -n -D /proc/bus/usb/005/006 -f ma006100.bin
Program received signal SIGSEGV, Segmentation fault.
0x00002b99c5643620 in strlen () from /lib/libc.so.6
(gdb) bt
#0 0x00002b99c5643620 in strlen () from /lib/libc.so.6
#1 0x00002b99c56137a7 in vfprintf () from /lib/libc.so.6
#2 0x00002b99c56141a6 in ?? () from /lib/libc.so.6
#3 0x00002b99c560fdaf in vfprintf () from /lib/libc.so.6
#4 0x0000000000400a8c in print (level=<value optimized out>, format=0x0, ap=0x7fffe56f89e0)
at madfuload.c:96
#5 0x0000000000400b43 in fatal (format=0x0) at madfuload.c:106
#6 0x000000000040132d in main (argc=6, argv=<value optimized out>) at madfuload.c:286
The variable format submitted to fatal is a NULL-pointer.
Another GDB session:
(gdb) br fatal
Breakpoint 1 at 0x400ab0: file madfuload.c, line 102.
(gdb) br print
Breakpoint 2 at 0x400a60: file madfuload.c, line 92.
(gdb) run
Starting program: ~/maudio/madfuload-1.2/madfuload -n -D /proc/bus/usb/005/005 -f /lib/firmware/2.6.17.3/maudio/m006100.bin
Breakpoint 1, fatal (format=0x4018b2 "cannot open %s: %s") at madfuload.c:102
102 {
(gdb) c
Continuing.
Breakpoint 2, print (level=3, format=0x4018b2 "cannot open %s: %s", ap=0x7fff67197430) at madfuload.c:92
92 {
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x00002b4943ba4620 in strlen () from /lib/libc.so.6
And yet another GDB session:
(gdb) br print
Breakpoint 1 at 0x400a60: file madfuload.c, line 92.
(gdb) run
Starting program: ~/maudio/madfuload-1.2/madfuload -n -D /proc/bus/usb/005/006 -f ma006100.bin
Breakpoint 1, print (level=3, format=0x4019d0 "cannot open %s: %s", ap=0x7fff17959c10) at madfuload.c:92
92 {
(gdb) s
93 if (to_logger) {
(gdb) s
96 vfprintf(stderr, format, ap);
(gdb) p format
$1 = 0x4019d0 "cannot open %s: %s"
(gdb) p ap
$2 = (struct __va_list_tag *) 0x7fff17959c10
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00002b9c933e2620 in strlen () from /lib/libc.so.6
(gdb) bt
#0 0x00002b9c933e2620 in strlen () from /lib/libc.so.6
#1 0x00002b9c933b27a7 in vfprintf () from /lib/libc.so.6
#2 0x00002b9c933b31a6 in ?? () from /lib/libc.so.6
#3 0x00002b9c933aedaf in vfprintf () from /lib/libc.so.6
#4 0x0000000000400a8c in print (level=<value optimized out>, format=0x0, ap=0x7fff17959c40)
at madfuload.c:96
#5 0x0000000000400b43 in fatal (format=0x0) at madfuload.c:106
#6 0x000000000040132d in main (argc=6, argv=<value optimized out>) at madfuload.c:286
For some reason I do not understand, on its way down to vfprintf, the "format" gets changed from a valid pointer to a NULL-pointer, causing madfuload to crash.
Regards, Thomas
Logged In: YES
user_id=2024809
Originator: YES
Forgot to mention, that it even does not work, if I specify the corrent files and device paths. :-)
Logged In: YES
user_id=2024809
Originator: YES
Forget my last comment!
If I specify the right filenames and devices pathes, it seems to be working. Unfortunately, I have absolutely no feedback as madfuload segfaults whenever it wants to print something on the screen. But since I am currently listening to music over the Transit USB, it must have been working somehow...
Logged In: YES
user_id=2024809
Originator: YES
And finally:
this is a quick and ugly patch, that allocates a char[256] array named stringbuffer and copies the format string into it, before passing it down to vfprintf.
I don't know if this breaks something (it surely does, my C skill are not only lame but also very rusty), but this way, no more segfaults on the way.
(gdb) br print
Breakpoint 1 at 0x400ad0: file madfuload.c, line 96.
(gdb) br fatal
Breakpoint 2 at 0x400c90: file madfuload.c, line 106.
(gdb) run
Starting program: ~/maudio/madfuload-1.2/madfuload.patched -D /proc/bus/usb/005/008 -n -f ma006100.bin
Breakpoint 2, fatal (format=0x401925 "cannot open %s: %s") at madfuload.c:106
106 {
(gdb) s
108 strcpy (stringbuf, format);
(gdb) s
106 {
(gdb) s
108 strcpy (stringbuf, format);
(gdb) s
106 {
(gdb) s
108 strcpy (stringbuf, format);
(gdb) p stringbuf
$1 = "%s: %d bytes read successfully", '\0' <repeats 225 times>
(gdb) p format
$2 = 0x401925 "cannot open %s: %s"
(gdb) s
110 va_start(ap, stringbuf);
(gdb) p stringbuf
$3 = "cannot open %s: %s\000uccessfully", '\0' <repeats 225 times>
(gdb) p format
$4 = <value optimized out>
(gdb) s
111 print(LOG_ERR, stringbuf, ap);
(gdb) s
110 va_start(ap, stringbuf);
(gdb) s
111 print(LOG_ERR, stringbuf, ap);
(gdb) s
110 va_start(ap, stringbuf);
(gdb) s
111 print(LOG_ERR, stringbuf, ap);
(gdb) s
Breakpoint 1, print (level=3, format=0x602440 "cannot open %s: %s", ap=0x7fff76bb6e70) at madfuload.c:96
96 {
(gdb) s
97 if (to_logger) {
(gdb) s
100 vfprintf(stderr, format, ap);
(gdb) s
cannot open /proc/bus/usb/005/008: No such file or directory101 putc('\n', stderr);
(gdb) c
Program exited with code 01.
(gdb)
File Added: madfuload.patch