Bug 1183781 - Fix leak in nsHostResolver r=sworkman
authorValentin Gosu <valentin.gosu@gmail.com>
Sat, 18 Jul 2015 00:22:45 +0200
changeset 253591 60d045b1c1a6998471ace6c999d5cf0b38c9a02e
parent 253590 8f4d9f74c3192ea0ed34f05d7e9882d877e7bfdc
child 253592 e65e02c8654495c3a1712ea0e789e96561a23855
push id29072
push usercbook@mozilla.com
push dateMon, 20 Jul 2015 09:36:58 +0000
treeherdermozilla-central@5df788c56ae7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssworkman
bugs1183781
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1183781 - Fix leak in nsHostResolver r=sworkman
netwerk/dns/nsHostResolver.cpp
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -466,16 +466,25 @@ HostDB_ClearEntry(PLDHashTable *table,
                     NetAddrToString(&addrElement->mAddress, buf, sizeof(buf));
                     LOG(("  [%s]\n", buf));
                 }
             }
             while (addrElement);
         }
     }
 #endif
+
+    {
+        MutexAutoLock lock(he->rec->addr_info_lock);
+        if (he->rec->addr_info) {
+            delete hr->addr_info;
+            he->rec->addr_info = nullptr;
+        }
+    }
+
     NS_RELEASE(he->rec);
 }
 
 static void
 HostDB_InitEntry(PLDHashEntryHdr *entry,
                  const void *key)
 {
     nsHostDBEnt *he = static_cast<nsHostDBEnt *>(entry);
@@ -848,18 +857,22 @@ nsHostResolver::ResolveHost(const char  
                         unspecHe->rec->HasUsableResult(now, flags)) {
 
                         MOZ_ASSERT(unspecHe->rec->addr_info || unspecHe->rec->negative,
                                    "Entry should be resolved or negative.");
 
                         LOG(("  Trying AF_UNSPEC entry for host [%s%s%s] af: %s.\n",
                              LOG_HOST(host, netInterface),
                              (af == PR_AF_INET) ? "AF_INET" : "AF_INET6"));
-
-                        he->rec->addr_info = nullptr;
+                        // Ensure existing `addr_info` in `he` is cleared before
+                        // copying from `unSpecHe`.
+                        if (he->rec->addr_info) {
+                            delete he->rec->addr_info;
+                            he->rec->addr_info = nullptr;
+                        }
                         if (unspecHe->rec->negative) {
                             he->rec->negative = unspecHe->rec->negative;
                             he->rec->CopyExpirationTimesAndFlagsFrom(unspecHe->rec);
                         } else if (unspecHe->rec->addr_info) {
                             // Search for any valid address in the AF_UNSPEC entry
                             // in the cache (not blacklisted and from the right
                             // family).
                             NetAddrElement *addrIter =