sa_len of 0 in ioctl paths, etc. and bogus routes
Bjoern A. Zeeb
bzeeb-lists at lists.zabbadoz.net
Sun Apr 9 12:55:11 UTC 2006
Hi,
attached patch and description is for testing and further discussion.
You can also fetch it from
http://sources.zabbadoz.net/freebsd/patchset/EXPERIMENTAL/sys-net-route.c.diff
!
! These checks are needed so we do not install a route looking
! like this:
! (0) 10.111.66.200 UH tun0 =>
!
! When removing this route the kernel will start to walk
! the address space which looks like a hang on amd64 because
! it'll take AGES and on 32bit arch might lead to an insta-panic
! when kernel debugging options are turned on.
!
! The problem is in rtrequest1:
! if (netmask) {
! rt_maskedcopy(dst, ndst, netmask);
! } else
! bcopy(dst, ndst, dst->sa_len);
!
! In both cases the len might be 0 if the application forgot to
! set it. This is an application error but as it can 'stall'
! your system upon removing of the bogus route it has to be
! prevented.
! If it is not ndst will be all-zero leading to above mentioned
! strange routes.
!
! I hit this twice using IOCTLs deprecated since rev. 1 of FreeBSD
! soure and still in the tree. They are descriped by Stevens and that
! might be the reason I had used them in my own code initially.
! Today I know exactly one application (after I had changed my own code)
! still using them and I just fixed usage of that.
!
! I haven't checked if this can also be triggered by using
! SIOCAIFADDR, etc.
!
! Looks good says: gnn
! Tested by: you?
!
! We should probably catch a sa_len of 0 as early as possible in ioctl paths
! too (suggested by gnn).
!
Index: route.c
===================================================================
RCS file: /shared/mirror/FreeBSD/r/ncvs/src/sys/net/route.c,v
retrieving revision 1.114
diff -u -p -r1.114 route.c
--- route.c 11 Nov 2005 16:04:48 -0000 1.114
+++ route.c 9 Apr 2006 12:12:38 -0000
@@ -499,6 +499,9 @@ rtrequest(int req,
{
struct rt_addrinfo info;
+ if (dst->sa_len == 0)
+ return(EINVAL);
+
bzero((caddr_t)&info, sizeof(info));
info.rti_flags = flags;
info.rti_info[RTAX_DST] = dst;
@@ -1137,6 +1140,9 @@ rtinit(struct ifaddr *ifa, int cmd, int
dst = ifa->ifa_addr;
netmask = ifa->ifa_netmask;
}
+ if (dst->sa_len == 0)
+ return(EINVAL);
+
/*
* If it's a delete, check that if it exists, it's on the correct
* interface or we might scrub a route to another ifa which would
--
Bjoern A. Zeeb bzeeb at Zabbadoz dot NeT
More information about the freebsd-net
mailing list