[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#601803: kfreebsd-image-8.1-1-686: ifconfig wlan0 create wlandev ath0 => SIOCIFCREATE2: Bad address



Petr Salinger <Petr.Salinger@seznam.cz> writes:
>    759 ifconfig CALL  __sysctl(0xbfbfddd0,0x6,0,0xbfbfdde8,0,0)
>    759 ifconfig SCTL  "net.routetable.0.0.3.0"
>    759 ifconfig RET   __sysctl 0

> but in debian
>    758 ifconfig CALL  __sysctl(0xbfbfe258,0x6,0xbfbfe030,0xbfbfe284,0,0)
>    758 ifconfig SCTL  "net.routetable.0.0.3.0"
>    758 ifconfig RET   __sysctl -1 errno 12 Cannot allocate memory
>
> But I do not know from where is this sysctl called.

(gdb) catch syscall sysctl
The feature 'catch syscall' is not supported on this architeture yet.

... too bad. This pushed me to port my instruction tracing pet project
to kfreebsd-i386:

$ git clone http://iki.fi/lindi/git/itrace.git/
$ cd itrace
$ gcc -o itrace.c -O2 itrace.c
$ sudo ./itrace -o i -s s -m m /sbin/ifconfig wlan1 create wlandev ath0
ifconfig: SIOCIFCREATE2: Bad address
$ ./itrace-decode1.py m < i > d
./itrace-decode1.py:13: DeprecationWarning: The popen2 module is deprecated.  Use the subprocess module.
  import sys, bisect, popen2, re, os
$ grep syscall\(202, s           
2141 syscall(202, -1077942660, 2, -1077942652, -1077942648, 0)
9716 syscall(202, -1077944132, 2, 671541444, -1077944124, 0)
144513 syscall(202, -1077942704, 2, 672841072, -1077942696, 0)
332886 syscall(202, -1077943640, 6, -1077944192, -1077943596, 0)
332919 syscall(202, -1077943640, 6, -1077945232, -1077943596, 0)
# => sysctl was called 5 times, matches with ifconfig.debian.txt
# => the first sysctl call was done after 2141 instructions had been executed
$ sed -n 2140,2145p d
280649db _dl_make_stack_executable+8699
28067dd0 calloc+7856
28067dd5 calloc+7861
28067dd7 calloc+7863
28067dd9 calloc+7865
280649e0 _dl_make_stack_executable+8704
# => sysctl call was made from address 0x28067dd5
$ sudo gdb --args /sbin/ifconfig wlan1 create wlandev ath0
Reading symbols from /sbin/ifconfig...done.
(gdb) break *0x28067dd5
Breakpoint 1 at 0x28067dd5
(gdb) r
Starting program: /sbin/ifconfig wlan1 create wlandev ath0

Breakpoint 1, 0x28067dd5 in ?? ()
(gdb) x/6i $eip
0x28067dd5:     int    $0x80
0x28067dd7:     jb     0x28067dda
0x28067dd9:     ret    
0x28067dda:     call   0x28068aa0
0x28067ddf:     add    $0x6215,%ecx
0x28067de5:     mov    %eax,0x8dc(%ecx)
(gdb) bt
#0  0x28067dd5 in ?? ()
#1  0x28054206 in ?? ()
#2  0x2806549c in ?? ()
#3  0x28052bcd in ?? ()
#4  0x280527b7 in ?? ()
# lost? huh?!
(gdb) shell cat /proc/$(pidof ifconfig)/maps
08048000-08052000 r-xp 0001e000 00:00 216919     /sbin/ifconfig
08052000-08053000 rw-p 0001e000 00:00 216919     /sbin/ifconfig
08053000-08054000 rw-p 00001000 00:00 0
28052000-2806d000 r-xp 0001d000 00:00 400397     /lib/ld-2.11.2.so
2806d000-2806e000 rw-p 0001d000 00:00 400397     /lib/ld-2.11.2.so
2806e000-2806f000 rw-p 00001000 00:00 0
bfbe0000-bfc00000 rwxp 00020000 00:00 0

# => the first sysctl is called from the dynamic linker?
 
(gdb) x/16a $esp
0xbfbfe618:     0x280649e0      0xbfbfe638      0x2     0xbfbfe640
0xbfbfe628:     0xbfbfe644      0x0     0x0     0x2806ebc0
0xbfbfe638:     0x1     0x18    0x2806eaa0      0x4
0xbfbfe648:     0x2806dff4      0x2806e8e8      0x39    0xbfbfe730

# => first argument == 0xbfbfe638 
# => second argument == 0x2
# => third argument == 0xbfbfe640
# => fourth argument == 0xbfbfe644
# => fifth argument == 0
# => sixth argument == 0

# 0x28067dd5 - 0x28052000 == 0x15dd5
$ objdump -aaxdt /usr/lib/debug/lib/ld-2.11.2.so | grep 15dd
00015dd0 l     F .text  00000020 __sysctl
00015dd0 l     F .text  00000020 sysctl
# 0x28054206 - 0x28052000 == 0x2206
$ objdump -axdt /lib/ld-2.11.2.so | grep -B2 2206
    21fb:       0f 84 a3 07 00 00       je     29a4 <free@plt+0x2218>
    2201:       e8 7a 07 01 00          call   12980 <_dl_make_stack_executable+0x21a0>
    2206:       85 c0                   test   %eax,%eax

# 0x2806549c - 0x28052000 == 0x1349c
$ objdump -axdt /lib/ld-2.11.2.so | grep -B2 1349c
   13496:       89 04 24                mov    %eax,(%esp)
   13499:       ff 55 0c                call   *0xc(%ebp)
   1349c:       8b 45 f0                mov    -0x10(%ebp),%eax

(gdb) x/32d 0xbfbfe638
0xbfbfe638:     1       0       0       0       24      0       0       0
# 1 == CTL_KERN, 24 == KERN_OSRELDATE

# => I am looking at the wrong sysctl call! it is not the first sysctl
# call that you are interested in but the fourth :-)

$ grep syscall\(202, s
2141 syscall(202, -1077942660, 2, -1077942652, -1077942648, 0)
9716 syscall(202, -1077944132, 2, 671541444, -1077944124, 0)
144513 syscall(202, -1077942704, 2, 672841072, -1077942696, 0)
332886 syscall(202, -1077943640, 6, -1077944192, -1077943596, 0)
332919 syscall(202, -1077943640, 6, -1077945232, -1077943596, 0)
$ sed -n 332919p d
2814c030 __sysctl+0

# => itrace's symbol decoding actually works after the dynamic linker
# has run... Now, let's look at the execution trace leading to the
# call:

$ sed -n 332910,332925p d
28166433 if_freenameindex+195
28166437 if_freenameindex+199
2816643a if_freenameindex+202
28166442 if_freenameindex+210
2816644a if_freenameindex+218
2816644e if_freenameindex+222
28166452 if_freenameindex+226
2816645a if_freenameindex+234
2816645d if_freenameindex+237
2814c030 __sysctl+0
2814c035 __sysctl+5
2814c037 __sysctl+7
2814c039 __sysctl+9
28166462 if_freenameindex+242
28166464 if_freenameindex+244
28166466 if_freenameindex+246

(gdb) break *0x2816645d
Breakpoint 2 at 0x2816645d
(gdb) c
Continuing.

Breakpoint 2, 0x2816645d in ?? ()
(gdb) bt
#0  0x2816645d in ?? ()
#1  0x2816659d in ?? ()
#2  0x08049b58 in main (argc=3, argv=0xbfbfe7d8) at ifconfig.c:245

(gdb) frame 2
#2  0x08049b58 in main (argc=3, argv=0xbfbfe7d8) at ifconfig.c:245
245                     ifindex = if_nametoindex(ifname);

# and indeed eglibc debian/patches/kfreebsd/local-sysdeps.diff 
# adds 

if_nametoindex (const char *ifname)
{
  struct nametoindex_locals l;

  l.name = ifname;
  l.index = 0;
  if_iterate (nametoindex_aux, &l);

  return l.index;
}

where if_iterate (if_fn fn, void *private) does

buf = alloca (bufsize);
if (__sysctl (request, 6, buf, &bufsize, NULL, 0) >= 0)



Are you still saying that it should pass zero as third argument?



Reply to: