Permalink
Browse files

make sure that route_output() does not override routing/ifaddr entrie…

…s due

to filtering for IPv6 scoped addresses.
  • Loading branch information...
jinmei
jinmei committed Aug 12, 2005
1 parent 46357c1 commit 6a13a06d7b516252a09d99824d9a83b0cd296f54
Showing with 58 additions and 34 deletions.
  1. +29 −17 netbsd/sys/net/rtsock.c
  2. +29 −17 openbsd/sys/net/rtsock.c
View
@@ -221,7 +221,7 @@ route_output(m, va_alist)
struct rtentry *rt = 0;
struct rtentry *saved_nrt = 0;
struct radix_node_head *rnh;
- struct rt_addrinfo info;
+ struct rt_addrinfo info, oinfo, *infop = NULL;
int len, error = 0;
struct ifnet *ifp = 0;
struct ifaddr *ifa = 0;
@@ -257,6 +257,7 @@ route_output(m, va_alist)
}
rtm->rtm_pid = curproc->p_pid;
memset(&info, 0, sizeof(info));
+ infop = &info;
info.rti_addrs = rtm->rtm_addrs;
if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info))
senderr(EINVAL);
@@ -284,6 +285,10 @@ route_output(m, va_alist)
suser(curproc->p_ucred, &curproc->p_acflag) != 0)
senderr(EACCES);
+ /* Remember the original array for possible filtering below */
+ oinfo = info;
+ infop = &oinfo;
+
switch (rtm->rtm_type) {
case RTM_ADD:
@@ -385,6 +390,8 @@ route_output(m, va_alist)
}
(void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm,
(struct walkarg *)0, 0);
+ /* rt_msg2() did the filtering, so we don't have to */
+ infop = NULL;
rtm->rtm_flags = rt->rt_flags;
rtm->rtm_rmx = rt->rt_rmx;
rtm->rtm_addrs = info.rti_addrs;
@@ -471,23 +478,28 @@ route_output(m, va_alist)
}
if (rtm) {
#ifdef INET6
- int i;
-
- /* Special filter for IPv6 scoped addresses (see rtmsg1()) */
- for (i = 0; i < RTAX_MAX; i++) {
- struct sockaddr *sa;
-
+ if (infop != NULL) {
+ int i;
- if ((sa = info.rti_info[i]) == NULL)
- continue;
- if ((char *)sa + sa->sa_len <=
- (char *)rtm + rtm->rtm_msglen &&
- sa->sa_len == sizeof(struct sockaddr_in6) &&
- sa->sa_family == AF_INET6) {
- struct sockaddr_in6 *sa6;
-
- sa6 = (struct sockaddr_in6 *)sa;
- (void)sa6_recoverscope(sa6);
+ /*
+ * Special filter for IPv6 scoped addresses
+ * (see rtmsg1())
+ */
+ for (i = 0; i < RTAX_MAX; i++) {
+ struct sockaddr *sa;
+
+ if ((sa = info.rti_info[i]) == NULL)
+ continue;
+ if ((char *)sa + sa->sa_len <=
+ (char *)rtm + rtm->rtm_msglen &&
+ sa->sa_len ==
+ sizeof(struct sockaddr_in6) &&
+ sa->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sa6;
+
+ sa6 = (struct sockaddr_in6 *)sa;
+ (void)sa6_recoverscope(sa6);
+ }
}
}
#endif
View
@@ -184,7 +184,7 @@ route_output(struct mbuf *m, ...)
struct rtentry *rt = NULL;
struct rtentry *saved_nrt = NULL;
struct radix_node_head *rnh;
- struct rt_addrinfo info;
+ struct rt_addrinfo info, oinfo, *infop = NULL;
int len, error = 0;
struct ifnet *ifp = NULL;
struct ifaddr *ifa = NULL;
@@ -225,6 +225,7 @@ route_output(struct mbuf *m, ...)
rtm->rtm_pid = curproc->p_pid;
bzero(&info, sizeof(info));
+ infop = &info;
info.rti_addrs = rtm->rtm_addrs;
rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info);
info.rti_flags = rtm->rtm_flags;
@@ -256,6 +257,10 @@ route_output(struct mbuf *m, ...)
goto flush;
}
+ /* Remember the original array for possible filtering below */
+ oinfo = info;
+ infop = &oinfo;
+
switch (rtm->rtm_type) {
case RTM_ADD:
if (gate == 0) {
@@ -369,6 +374,8 @@ route_output(struct mbuf *m, ...)
Free(rtm); rtm = new_rtm;
}
rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm, NULL);
+ /* rt_msg2() did the filtering, so we don't have to */
+ infop = NULL;
rtm->rtm_flags = rt->rt_flags;
rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx);
rtm->rtm_addrs = info.rti_addrs;
@@ -455,23 +462,28 @@ route_output(struct mbuf *m, ...)
route_proto.sp_protocol = dst->sa_family;
if (rtm) {
#ifdef INET6
- int i;
-
- /* Special filter for IPv6 scoped addresses (see rtmsg1()) */
- for (i = 0; i < RTAX_MAX; i++) {
- struct sockaddr *sa;
-
+ if (infop != NULL) {
+ int i;
- if ((sa = info.rti_info[i]) == NULL)
- continue;
- if ((char *)sa + sa->sa_len <=
- (char *)rtm + rtm->rtm_msglen &&
- sa->sa_len == sizeof(struct sockaddr_in6) &&
- sa->sa_family == AF_INET6) {
- struct sockaddr_in6 *sa6;
-
- sa6 = (struct sockaddr_in6 *)sa;
- (void)sa6_recoverscope(sa6);
+ /*
+ * Special filter for IPv6 scoped addresses
+ * (see rtmsg1())
+ */
+ for (i = 0; i < RTAX_MAX; i++) {
+ struct sockaddr *sa;
+
+ if ((sa = info.rti_info[i]) == NULL)
+ continue;
+ if ((char *)sa + sa->sa_len <=
+ (char *)rtm + rtm->rtm_msglen &&
+ sa->sa_len ==
+ sizeof(struct sockaddr_in6) &&
+ sa->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sa6;
+
+ sa6 = (struct sockaddr_in6 *)sa;
+ (void)sa6_recoverscope(sa6);
+ }
}
}
#endif

0 comments on commit 6a13a06

Please sign in to comment.