Hi, I'am new in Mac OS X kernel development
and I'am experienced this problem:
1. I have clear OS with tun/tap interface
installed. (This tun/tap is developed by me but the same behaviour occured with
free tun/tap which you can find on Internet)
2. open device => attach net iface (ifnet_attach with uniqueid == MAC)
3. ifconfig "name-of-iface" 172.16.1.1-24 alias
(yes, we are trying to add secondary IP to interface with no one
IP)
4. everything is ok, we have iface with IP
172.16.1.1
5. close device => detach iface with
iface_detach (during process off detaching we called ifnet_detach_protocol and another relevant detaching
functions)
6. everything is ok, we have not iface in
OS
7. open device => attach net iface (iface_attach
with uniqueid == MAC [identical to MAC in second step])
8. ifconfig "name-of-iface" 172.16.1.1-24 alias
9. panic crash
This crash occures only on Leopard OS by reason of
minority changes in BSD kernel (xnu-1228\bsd\netinet\in.c:1192) ifafree function
is trying to dereference NULL pointer previously obtained by ifa_ifpgetprimary()
Why this pointer is NULL ? The reason is in incoherence between if_addrhead (list with addresses on iface) and in_ifaddrhead
(list with all(?) IP ) Another reason is reusing detached iface. When you detach
iface from system, iface still remain in system waiting for another chance to
live. No iface memory is released, no address memory is
released. If you will call iface_attach with the same uniqueid, system will
return back the same iface which you are allocated for the first time.
BUT during processing of iface_attach function, if_addrhead list is
initialized and filled with link layer address. This means that
in this list will be only one address with family AF_LINK but
no address with AF_INET family. But in in_ifaddrhead is still AF_INET address
which leads to our iface. And this is incoherence mentioned above. When you
call ifconfig ... alias, system try to ADD ip but not call REMOVE (as in the
case of ifconfig .... wihout alias) OS will find address in in_ifaddrhead
(xnu-1228\bsd\netinet\in.c:307) and will not call if_attach_ifa to add new address to if_addrhead. Next,
in_ifinit() is called (xnu-1228\bsd\netinet\in.c:702) in this
function ifa_ifpgetprimary() is called but this routine search in
if_addrhead on iface) In this list is only one address (link layer) and no
AF_INET. This means that NULL pointer is returned and panic crash will occure on
next call to
ifafree.
My question is: Is this a bug in BSD portion of
kernel and should be reported to Apple, or behaviour of my kernel module is
inccorect ?
Workaround is to call ifnet_attach with unique id,
but in this case some leaks can occure....
P.S. I'am sorry for my bad english, I
will try to improve my language skills :-)
Thanks,
Ondrej
Slanina
developer
..................................................................
Kerio
Technologies s.r.o.
Anglicke nabrezi 1, 301 49 Plzen
Czech Republic
http://www.kerio.com
...................................................................
Connect.
Communicate. Collaborate. Securely.