/* * usage is easy, though not very friendly: * gcc reg-bug.c * ./a.out | od -tx4 * * if the values outputted by hexdump are different the 'bug' is present * else the bug is not present * on a system without the bug: dvorak$ dmesg | head -1 Linux version 2.2.21 (kernel@debian) (gcc version 2.95.4 20011002 (Debian prerelease)) #6 Sat Sep 7 22:48:42 CEST 2002 dvorak$ gcc reg-bug.c dvorak$ ./a.out | od -tx4 0000000 bff7de6c bff7de6c * on a 'buggy' system: * (m4xx) dmesg | head -1 (m4xx) Linux version 2.4.18 (maxx@meuuh) (gcc version 2.95.4 20011002 (Debian +prerelease)) #2 Mon Jul 29 17:01:30 CEST 2002 (m4xx) $ gcc reg-bug.c (m4xx) $ ./a.out | od -tx4 (m4xx) 0000000 bffffdcc bffffdbc */ int main(void) { __asm__(" pushl $0x00010001 # this is events and revents pushl $0x0 # fd 0 pushl $0x00010001 # again events and revents pushl $0x1 # fd 1 movl %esp, %ebx # %ebx now contains a pointer to the # pollfd structure i setted up, # note that only pushes occur # below so this structures stays on the stack pushl %ebx # we pushl %ebx to compare it later movl $0x2, %ecx # 2 = number of fd's movl $0xa8, %eax # __NR_sys_poll movl $(-1), %edx # no timeout int $0x80 # call kernel # sys_poll(%ebx, %ecx, %edx) # %ebx == ufds (address of the pollfd structs)o # %ecx == num fd's (2) # %edx == timeout (-1) pushl %ebx # we push the returned %ebx on the stack # as well movl %esp, %ecx # %ecx is now pointer to the 2 saved %ebx's movl $0x08, %edx # %edx = 8 movl $0x04, %eax # %eax = 4 == __NR_sys_write movl $0x01, %ebx # %ebx = 1 == fd int $0x80 # call kernel # sys_write(%ebx, %ecx, %edx) # %ebx = fd (1) # %ecx = buf (pointer to the 2 saved %ebx's) # %edx = len (8) movl $0x01, %eax # and an sys_exit(0); xorl %ebx, %ebx int $0x80 "); }