mknod() broken with uclibc built with -O0
Tino Keitel
tino.keitel at innominate.com
Thu Dec 11 14:00:48 UTC 2008
On Thu, Dec 11, 2008 at 02:02:07 +0100, Denys Vlasenko wrote:
[...]
> Can you try smaller test program? A-la
>
> #include <bare_minimum_for_bug_to_happen.h>
> int main() {
> mknod("foobar", 0755, makedev(10,63));
> return 0;
> }
>
> If this works, add more stuff until it breaks.
> Tell us what broke it. Show gcc -On -S results.
Here is the test program:
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main() {
mknod("foobar", S_IFCHR|0666, makedev(10,63));
return 0;
}
$ strace ./test_static
execve("./test_static", ["./test_static"], [/* 18 vars */]) = 0
mknod("foobar", S_IFCHR|0666, makedev(10, 63)) = 0
_exit(0)
So this works as it should. I added a puts("foobar"); after the
mknod(), and this broke:
$ strace ./test_static_stdio_puts
execve("./test_static_stdio_puts", ["./test_static_stdio_puts"], [/* 18
vars */]) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo
...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo
...}) = 0
mknod("foobar", S_IFCHR|01001000666, makedev(4294965514, 4294967103)) =
0
write(1, "foobar\n"..., 7foobar
) = 7
_exit(0) = ?
$
Another side effect: the device node created with the broken version is
shown correctly in ls inside the buildroot chroot:
crw-r--r-- 1 root root 10, 63 Dec 11 06:55 foobar
The major/minor nummers are shown correctly using the tools of the host
system (outside the chroot):
crw-r--r-- 1 root root 2314, 1048383 Dec 11 14:55 foobar
Here is the assembly of the broken version:
.file "test.c"
.section .rodata
.LC0:
.string "foobar"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $4, %esp
subl $8, %esp
pushl $63
pushl $10
call gnu_dev_makedev
addl $16, %esp
pushl %edx
pushl %eax
pushl $8630
pushl $.LC0
call mknod
addl $16, %esp
subl $12, %esp
pushl $.LC0
call puts
addl $16, %esp
movl $0, %eax
movl -4(%ebp), %ecx
leave
leal -4(%ecx), %esp
ret
.size main, .-main
.type gnu_dev_makedev, @function
gnu_dev_makedev:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
movl 12(%ebp), %eax
movzbl %al,%edx
movl 8(%ebp), %eax
andl $4095, %eax
sall $8, %eax
orl %edx, %eax
movl %eax, %esi
movl $0, %edi
movl 12(%ebp), %ecx
movl $0, %ebx
movl %ecx, %eax
movb $0, %al
movl %ebx, %edx
andl $0, %edx
shldl $12, %eax, %edx
sall $12, %eax
movl %esi, %ecx
orl %eax, %ecx
movl %edi, %ebx
orl %edx, %ebx
movl 8(%ebp), %esi
movl $0, %edi
movl %esi, %eax
andl $-4096, %eax
movl %edi, %edx
andl $0, %edx
movl %eax, %esi
movl %edx, %edi
movl %esi, %edi
movl $0, %esi
movl %ecx, %eax
orl %esi, %eax
movl %ebx, %edx
orl %edi, %edx
popl %ebx
popl %esi
popl %edi
leave
ret
.size gnu_dev_makedev, .-gnu_dev_makedev
.ident "GCC: (GNU) 4.3.2"
.section .note.GNU-stack,"", at progbits
Regards,
Tino
--
Tino Keitel
Software Engineer
Innominate Security Technologies AG
/protecting industrial networks/
Tel: +49.30.6392-3309
Fax: +49.30.6392-3307
Albert-Einstein-Str. 14
D-12489 Berlin
http://www.innominate.com/
Register Court: AG Charlottenburg, HRB 81603
Management Board: Dirk Seewald
Chairman of the Supervisory Board: Volker Bibelhausen
INNOMINATE IS MOVING. FROM 17.12.2008 OUR BUSINESS CONTACT DATA WILL BE
CHANGED:
Rudower Chaussee 13, 12489Berlin / Germany
tel: +49.30.921028-0 (head office)
tel: +49.30.921028-206 (personal extension)
fax: +49.30. 921028-020
More information about the uClibc
mailing list