]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fix type mismatch in new/delete of addrinfo::ai_addr (#2136) master
authorBen Kallus <49924171+kenballus@users.noreply.github.com>
Mon, 11 Aug 2025 13:02:17 +0000 (13:02 +0000)
committerSquid Anubis <squid-anubis@squid-cache.org>
Thu, 14 Aug 2025 02:50:45 +0000 (02:50 +0000)
new/delete type mismatches are UB. Fix an instance of this
problem that occurs when sockaddr_in6 is allocated, but
sockaddr is deallocated, by always allocating/deallocating
sockaddr_storage.

    AddressSanitizer: new-delete-type-mismatch:
      object passed to delete has wrong type:
      size of the allocated type:   28 bytes;
      size of the deallocated type: 16 bytes.
    #0 0xaaaad1a8db54 in operator delete(void*, unsigned long)
    #1 0xaaaad287a668 in Ip::Address::FreeAddr(addrinfo*&)
        src/ip/Address.cc:710:22

src/ip/Address.cc

index af2a58fcb90bcd4c5774c98ca69a51eea5f7be09..f302367e642aaf1662014fd48fbd32f01f7ce2e8 100644 (file)
@@ -643,11 +643,8 @@ Ip::Address::getAddrInfo(struct addrinfo *&dst, int force) const
             && dst->ai_protocol == 0)
         dst->ai_protocol = IPPROTO_UDP;
 
+    InitAddr(dst);
     if (force == AF_INET6 || (force == AF_UNSPEC && isIPv6()) ) {
-        dst->ai_addr = (struct sockaddr*)new sockaddr_in6;
-
-        memset(dst->ai_addr,0,sizeof(struct sockaddr_in6));
-
         getSockAddr(*((struct sockaddr_in6*)dst->ai_addr));
 
         dst->ai_addrlen = sizeof(struct sockaddr_in6);
@@ -669,11 +666,6 @@ Ip::Address::getAddrInfo(struct addrinfo *&dst, int force) const
 #endif
 
     } else if ( force == AF_INET || (force == AF_UNSPEC && isIPv4()) ) {
-
-        dst->ai_addr = (struct sockaddr*)new sockaddr_in;
-
-        memset(dst->ai_addr,0,sizeof(struct sockaddr_in));
-
         getSockAddr(*((struct sockaddr_in*)dst->ai_addr));
 
         dst->ai_addrlen = sizeof(struct sockaddr_in);
@@ -693,12 +685,12 @@ Ip::Address::InitAddr(struct addrinfo *&ai)
     }
 
     // remove any existing data.
-    if (ai->ai_addr) delete ai->ai_addr;
+    delete reinterpret_cast<struct sockaddr_storage *>(ai->ai_addr);
 
-    ai->ai_addr = (struct sockaddr*)new sockaddr_in6;
-    memset(ai->ai_addr, 0, sizeof(struct sockaddr_in6));
+    ai->ai_addr = reinterpret_cast<struct sockaddr *>(new sockaddr_storage);
+    memset(ai->ai_addr, 0, sizeof(struct sockaddr_storage));
 
-    ai->ai_addrlen = sizeof(struct sockaddr_in6);
+    ai->ai_addrlen = sizeof(struct sockaddr_storage);
 
 }
 
@@ -707,7 +699,7 @@ Ip::Address::FreeAddr(struct addrinfo *&ai)
 {
     if (ai == nullptr) return;
 
-    if (ai->ai_addr) delete ai->ai_addr;
+    delete reinterpret_cast<struct sockaddr_storage *>(ai->ai_addr);
 
     ai->ai_addr = nullptr;