diff options
author | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2021-02-20 18:21:52 +0000 |
---|---|---|
committer | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2021-02-20 18:26:35 +0000 |
commit | e5b394f2d0d94f190c9da2346fd22d7c6fb14730 (patch) | |
tree | 152f1ecc4064424a208af059458f8e21944a7798 /sys/net | |
parent | 020f4112559ebf7e94665c9a69f89d21929ce82a (diff) | |
download | src-e5b394f2d0d94f190c9da2346fd22d7c6fb14730.tar.gz src-e5b394f2d0d94f190c9da2346fd22d7c6fb14730.zip |
Fix setting static entries for arp/ndp.
rtsock message validation changes committed in 2fe5a79425c7
did not take llinfo messages into account.
Add a special validation case for RTA_GATEWAY llinfo messages.
MFC after: 2 days
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_llatbl.c | 1 | ||||
-rw-r--r-- | sys/net/rtsock.c | 26 |
2 files changed, 27 insertions, 0 deletions
diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index 97a8e3e9ccc1..7225869a07d0 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -693,6 +693,7 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info) if (dl == NULL || dl->sdl_family != AF_LINK) return (EINVAL); + /* XXX: should be ntohs() */ ifp = ifnet_byindex(dl->sdl_index); if (ifp == NULL) { log(LOG_INFO, "%s: invalid ifp (sdl_index %d)\n", diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 221661585bbf..12e485f917c8 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1323,11 +1323,37 @@ fill_sockaddr_inet6(struct sockaddr_in6 *sin6, const struct in6_addr *addr6, } #endif +/* + * Checks if gateway is suitable for lltable operations. + * Lltable code requires AF_LINK gateway with ifindex + * and mac address specified. + * Returns 0 on success. + */ +static int +cleanup_xaddrs_lladdr(struct rt_addrinfo *info) +{ + struct sockaddr_dl *sdl = (struct sockaddr_dl *)info->rti_info[RTAX_GATEWAY]; + + if (sdl->sdl_family != AF_LINK) + return (EINVAL); + + if (sdl->sdl_index == 0) + return (EINVAL); + + if (offsetof(struct sockaddr_dl, sdl_data) + sdl->sdl_nlen + sdl->sdl_alen > sdl->sdl_len) + return (EINVAL); + + return (0); +} + static int cleanup_xaddrs_gateway(struct rt_addrinfo *info) { struct sockaddr *gw = info->rti_info[RTAX_GATEWAY]; + if (info->rti_flags & RTF_LLDATA) + return (cleanup_xaddrs_lladdr(info)); + switch (gw->sa_family) { #ifdef INET case AF_INET: |