From owner-svn-src-vendor@freebsd.org Mon Jun 8 20:35:04 2020 Return-Path: Delivered-To: svn-src-vendor@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 3009433AB56; Mon, 8 Jun 2020 20:35:04 +0000 (UTC) (envelope-from cy@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49glP40VD3z4TbQ; Mon, 8 Jun 2020 20:35:04 +0000 (UTC) (envelope-from cy@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0BCC6A723; Mon, 8 Jun 2020 20:35:04 +0000 (UTC) (envelope-from cy@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 058KZ3aa050990; Mon, 8 Jun 2020 20:35:03 GMT (envelope-from cy@FreeBSD.org) Received: (from cy@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 058KZ3H1050988; Mon, 8 Jun 2020 20:35:03 GMT (envelope-from cy@FreeBSD.org) Message-Id: <202006082035.058KZ3H1050988@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cy set sender to cy@FreeBSD.org using -f From: Cy Schubert Date: Mon, 8 Jun 2020 20:35:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r361936 - vendor/wpa/dist/src/wps X-SVN-Group: vendor X-SVN-Commit-Author: cy X-SVN-Commit-Paths: vendor/wpa/dist/src/wps X-SVN-Commit-Revision: 361936 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Jun 2020 20:35:04 -0000 Author: cy Date: Mon Jun 8 20:35:03 2020 New Revision: 361936 URL: https://svnweb.freebsd.org/changeset/base/361936 Log: Upstream commit message: [PATCH 1/3] WPS UPnP: Do not allow event subscriptions with URLs to other networks The UPnP Device Architecture 2.0 specification errata ("UDA errata 16-04-2020.docx") addresses a problem with notifications being allowed to go out to other domains by disallowing such cases. Do such filtering for the notification callback URLs to avoid undesired connections to external networks based on subscriptions that any device in the local network could request when WPS support for external registrars is enabled (the upnp_iface parameter in hostapd configuration). Obtained from: https://w1.fi/security/2020-1/\ 0001-WPS-UPnP-Do-not-allow-event-subscriptions-with-URLs-.patch MFC after: 1 week Security: VU#339275 and CVE-2020-12695 Modified: vendor/wpa/dist/src/wps/wps_er.c vendor/wpa/dist/src/wps/wps_upnp.c vendor/wpa/dist/src/wps/wps_upnp_i.h Modified: vendor/wpa/dist/src/wps/wps_er.c ============================================================================== --- vendor/wpa/dist/src/wps/wps_er.c Mon Jun 8 20:28:32 2020 (r361935) +++ vendor/wpa/dist/src/wps/wps_er.c Mon Jun 8 20:35:03 2020 (r361936) @@ -1298,7 +1298,7 @@ wps_er_init(struct wps_context *wps, const char *ifnam "with %s", filter); } if (get_netif_info(er->ifname, &er->ip_addr, &er->ip_addr_text, - er->mac_addr)) { + NULL, er->mac_addr)) { wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address " "for %s. Does it have IP address?", er->ifname); wps_er_deinit(er, NULL, NULL); Modified: vendor/wpa/dist/src/wps/wps_upnp.c ============================================================================== --- vendor/wpa/dist/src/wps/wps_upnp.c Mon Jun 8 20:28:32 2020 (r361935) +++ vendor/wpa/dist/src/wps/wps_upnp.c Mon Jun 8 20:35:03 2020 (r361936) @@ -303,6 +303,14 @@ static void subscr_addr_free_all(struct subscription * } +static int local_network_addr(struct upnp_wps_device_sm *sm, + struct sockaddr_in *addr) +{ + return (addr->sin_addr.s_addr & sm->netmask.s_addr) == + (sm->ip_addr & sm->netmask.s_addr); +} + + /* subscr_addr_add_url -- add address(es) for one url to subscription */ static void subscr_addr_add_url(struct subscription *s, const char *url, size_t url_len) @@ -381,6 +389,7 @@ static void subscr_addr_add_url(struct subscription *s for (rp = result; rp; rp = rp->ai_next) { struct subscr_addr *a; + struct sockaddr_in *addr = (struct sockaddr_in *) rp->ai_addr; /* Limit no. of address to avoid denial of service attack */ if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) { @@ -389,6 +398,13 @@ static void subscr_addr_add_url(struct subscription *s break; } + if (!local_network_addr(s->sm, addr)) { + wpa_printf(MSG_INFO, + "WPS UPnP: Ignore a delivery URL that points to another network %s", + inet_ntoa(addr->sin_addr)); + continue; + } + a = os_zalloc(sizeof(*a) + alloc_len); if (a == NULL) break; @@ -889,11 +905,12 @@ static int eth_get(const char *device, u8 ea[ETH_ALEN] * @net_if: Selected network interface name * @ip_addr: Buffer for returning IP address in network byte order * @ip_addr_text: Buffer for returning a pointer to allocated IP address text + * @netmask: Buffer for returning netmask or %NULL if not needed * @mac: Buffer for returning MAC address * Returns: 0 on success, -1 on failure */ int get_netif_info(const char *net_if, unsigned *ip_addr, char **ip_addr_text, - u8 mac[ETH_ALEN]) + struct in_addr *netmask, u8 mac[ETH_ALEN]) { struct ifreq req; int sock = -1; @@ -919,6 +936,19 @@ int get_netif_info(const char *net_if, unsigned *ip_ad in_addr.s_addr = *ip_addr; os_snprintf(*ip_addr_text, 16, "%s", inet_ntoa(in_addr)); + if (netmask) { + os_memset(&req, 0, sizeof(req)); + os_strlcpy(req.ifr_name, net_if, sizeof(req.ifr_name)); + if (ioctl(sock, SIOCGIFNETMASK, &req) < 0) { + wpa_printf(MSG_ERROR, + "WPS UPnP: SIOCGIFNETMASK failed: %d (%s)", + errno, strerror(errno)); + goto fail; + } + addr = (struct sockaddr_in *) &req.ifr_netmask; + netmask->s_addr = addr->sin_addr.s_addr; + } + #ifdef __linux__ os_strlcpy(req.ifr_name, net_if, sizeof(req.ifr_name)); if (ioctl(sock, SIOCGIFHWADDR, &req) < 0) { @@ -1025,11 +1055,15 @@ static int upnp_wps_device_start(struct upnp_wps_devic /* Determine which IP and mac address we're using */ if (get_netif_info(net_if, &sm->ip_addr, &sm->ip_addr_text, - sm->mac_addr)) { + &sm->netmask, sm->mac_addr)) { wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address " "for %s. Does it have IP address?", net_if); goto fail; } + wpa_printf(MSG_DEBUG, "WPS UPnP: Local IP address %s netmask %s hwaddr " + MACSTR, + sm->ip_addr_text, inet_ntoa(sm->netmask), + MAC2STR(sm->mac_addr)); /* Listen for incoming TCP connections so that others * can fetch our "xml files" from us. Modified: vendor/wpa/dist/src/wps/wps_upnp_i.h ============================================================================== --- vendor/wpa/dist/src/wps/wps_upnp_i.h Mon Jun 8 20:28:32 2020 (r361935) +++ vendor/wpa/dist/src/wps/wps_upnp_i.h Mon Jun 8 20:35:03 2020 (r361936) @@ -128,6 +128,7 @@ struct upnp_wps_device_sm { u8 mac_addr[ETH_ALEN]; /* mac addr of network i.f. we use */ char *ip_addr_text; /* IP address of network i.f. we use */ unsigned ip_addr; /* IP address of network i.f. we use (host order) */ + struct in_addr netmask; int multicast_sd; /* send multicast messages over this socket */ int ssdp_sd; /* receive discovery UPD packets on socket */ int ssdp_sd_registered; /* nonzero if we must unregister */ @@ -158,7 +159,7 @@ struct subscription * subscription_find(struct upnp_wp const u8 uuid[UUID_LEN]); void subscr_addr_delete(struct subscr_addr *a); int get_netif_info(const char *net_if, unsigned *ip_addr, char **ip_addr_text, - u8 mac[ETH_ALEN]); + struct in_addr *netmask, u8 mac[ETH_ALEN]); /* wps_upnp_ssdp.c */ void msearchreply_state_machine_stop(struct advertisement_state_machine *a);