summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2023-11-12 16:10:47 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2023-11-12 16:10:47 +0000
commit0414652b1de8a5cf43714add736ea0d7f96445f0 (patch)
tree1d146b75a3e0b6019d5e50beda11f6b27028d7f8 /sys/net
parentda75bd6d2e3743f414a6e28b8f8bf0c8a70f6da4 (diff)
Do not modify route info sockaddr in rtm_xaddrs().
The rti_info array is used to describe routes that should be found by lookup. Modifying the addreses in it is not a good idea. There were places where rtm_xaddrs() tried to fix the address family instead of validating it. Replace the modification with a check and error out with EAFNOSUPPORT on failure. Route labels always have AF_UNSPEC and the other types are not used anyway. OK kn@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/rtsock.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index d7b6d1907a3..3d252397982 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.370 2023/09/16 09:33:27 mpi Exp $ */
+/* $OpenBSD: rtsock.c,v 1.371 2023/11/12 16:10:46 bluhm Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -1416,8 +1416,7 @@ rtm_getmetrics(const struct rtentry *rt, struct rt_metrics *out)
int
rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
{
- struct sockaddr *sa;
- int i;
+ int i;
/*
* Parse address bits, split address storage in chunks, and
@@ -1426,6 +1425,8 @@ rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
*/
bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info));
for (i = 0; i < sizeof(rtinfo->rti_addrs) * 8; i++) {
+ struct sockaddr *sa;
+
if ((rtinfo->rti_addrs & (1U << i)) == 0)
continue;
if (i >= RTAX_MAX || cp + sizeof(socklen_t) > cplim)
@@ -1443,6 +1444,7 @@ rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
* be NUL terminated.
*/
for (i = 0; i < RTAX_MAX; i++) {
+ const struct sockaddr *sa;
size_t len, maxlen, size;
sa = rtinfo->rti_info[i];
@@ -1497,13 +1499,15 @@ rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
}
break;
case RTAX_LABEL:
- sa->sa_family = AF_UNSPEC;
+ if (sa->sa_family != AF_UNSPEC)
+ return (EAFNOSUPPORT);
maxlen = RTLABEL_LEN;
size = sizeof(struct sockaddr_rtlabel);
break;
#ifdef BFD
case RTAX_BFD:
- sa->sa_family = AF_UNSPEC;
+ if (sa->sa_family != AF_UNSPEC)
+ return (EAFNOSUPPORT);
size = sizeof(struct sockaddr_bfd);
break;
#endif
@@ -1525,12 +1529,21 @@ rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
}
break;
case RTAX_STATIC:
- sa->sa_family = AF_UNSPEC;
+ switch (sa->sa_family) {
+ case AF_INET:
+#ifdef INET6
+ case AF_INET6:
+#endif
+ break;
+ default:
+ return (EAFNOSUPPORT);
+ }
maxlen = RTSTATIC_LEN;
size = sizeof(struct sockaddr_rtstatic);
break;
case RTAX_SEARCH:
- sa->sa_family = AF_UNSPEC;
+ if (sa->sa_family != AF_UNSPEC)
+ return (EAFNOSUPPORT);
maxlen = RTSEARCH_LEN;
size = sizeof(struct sockaddr_rtsearch);
break;