Stefan Dösinger : iphlpapi: Honor sa_len when reading AF_INET addresses.

Alexandre Julliard julliard at winehq.org
Wed Apr 22 15:29:28 CDT 2020


Module: wine
Branch: master
Commit: f3b64f950f2cbed96ded71a6b0526c4621434d39
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f3b64f950f2cbed96ded71a6b0526c4621434d39

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sun Apr 12 14:24:57 2020 +0200

iphlpapi: Honor sa_len when reading AF_INET addresses.

Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/iphlpapi/ipstats.c | 52 +++++++++++++++++++++++++------------------------
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index 61f3a97ec4..11d52d4d65 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -1548,33 +1548,35 @@ DWORD WINAPI AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE *ppIpForw
 
              ADVANCE (addrPtr, sa);
 
-             /* default routes are encoded by length-zero sockaddr */
-             if (sa->sa_len == 0) {
-                addr = 0;
-             }else {
-                 /* Apple's netstat prints the netmask together with the destination
-                  * and only looks at the destination's address family. The netmask's
-                  * sa_family sometimes contains the non-existent value 0xff. */
-                 switch(i == RTA_NETMASK ? dst_family : sa->sa_family) {
-                 case AF_INET: {
-                     struct sockaddr_in *sin = (struct sockaddr_in *)sa;
-                     addr = sin->sin_addr.s_addr;
-                     break;
-                 }
+             /* Apple's netstat prints the netmask together with the destination
+              * and only looks at the destination's address family. The netmask's
+              * sa_family sometimes contains the non-existent value 0xff. */
+             switch(i == RTA_NETMASK ? dst_family : sa->sa_family) {
+             case AF_INET: {
+                 /* Netmasks (and possibly other addresses) have only enough size
+                  * to represent the non-zero bits, e.g. a netmask of 255.0.0.0 has
+                  * 5 bytes (1 sa_len, 1 sa_family, 2 sa_port and 1 for the first
+                  * byte of sin_addr). Due to the alignment constraint we can de
+                  * facto read the full 4 bytes of sin_addr (except for the case of
+                  * netmask 0). Don't assume though that the extra bytes are zeroed. */
+                 struct sockaddr_in sin = {0};
+                 memcpy(&sin, sa, sa->sa_len);
+                 addr = sin.sin_addr.s_addr;
+                 break;
+             }
 #ifdef AF_LINK
-                 case AF_LINK:
-                     if(i == RTA_GATEWAY && row.u1.ForwardType == MIB_IPROUTE_TYPE_DIRECT) {
-                         /* For direct route we may simply use dest addr as next hop */
-                         C_ASSERT(RTA_DST < RTA_GATEWAY);
-                         addr = row.dwForwardDest;
-                         break;
-                     }
-                     /* fallthrough */
-#endif
-                 default:
-                     WARN ("Received unsupported sockaddr family 0x%x\n", sa->sa_family);
-                     addr = 0;
+             case AF_LINK:
+                 if(i == RTA_GATEWAY && row.u1.ForwardType == MIB_IPROUTE_TYPE_DIRECT) {
+                     /* For direct route we may simply use dest addr as next hop */
+                     C_ASSERT(RTA_DST < RTA_GATEWAY);
+                     addr = row.dwForwardDest;
+                     break;
                  }
+             /* fallthrough */
+#endif
+             default:
+                 WARN ("Received unsupported sockaddr family 0x%x\n", sa->sa_family);
+                 addr = 0;
              }
 
              switch (i)




More information about the wine-cvs mailing list