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.