components/squid/patches/CVE-2013-4115.patch
changeset 1592 1b2aaf6ad5a7
equal deleted inserted replaced
1591:24aca88f3e99 1592:1b2aaf6ad5a7
       
     1 Fix for CVE-2013-4115
       
     2 
       
     3 Buffer overflow in the idnsALookup function in dns_internal.cc in Squid
       
     4 3.2 through 3.2.11 and 3.3 through 3.3.6 allows remote attackers to
       
     5 cause a denial of service (memory corruption and server termination)
       
     6 via a long name in a DNS lookup request.
       
     7 
       
     8 See http://www.squid-cache.org/Advisories/SQUID-2013_2.txt
       
     9 
       
    10 The patch comes from
       
    11 http://www.squid-cache.org/Versions/v3/3.1/changesets/squid-3.1-10487.patch
       
    12 
       
    13 --- squid-3.1.23-orig/src/dns_internal.cc	2013-01-08 18:15:21.000000000 -0800
       
    14 +++ squid-3.1.23/src/dns_internal.cc	2013-12-10 14:09:08.983526000 -0800
       
    15 @@ -1532,22 +1532,26 @@
       
    16  void
       
    17  idnsALookup(const char *name, IDNSCB * callback, void *data)
       
    18  {
       
    19 -    unsigned int i;
       
    20 -    int nd = 0;
       
    21 -    idns_query *q;
       
    22 +    size_t nameLength = strlen(name);
       
    23  
       
    24 -    if (idnsCachedLookup(name, callback, data))
       
    25 +    // Prevent buffer overflow on q->name
       
    26 +    if (nameLength > NS_MAXDNAME) {
       
    27 +        debugs(23, DBG_IMPORTANT, "SECURITY ALERT: DNS name too long to perform lookup: '" << name << "'. see access.log for details.");
       
    28 +        callback(data, NULL, 0, "Internal error");
       
    29          return;
       
    30 +    }
       
    31  
       
    32 -    q = cbdataAlloc(idns_query);
       
    33 +    if (idnsCachedLookup(name, callback, data))
       
    34 +        return;
       
    35  
       
    36 +    idns_query *q = cbdataAlloc(idns_query);
       
    37      q->id = idnsQueryID();
       
    38 -
       
    39 -    for (i = 0; i < strlen(name); i++)
       
    40 +    int nd = 0;
       
    41 +    for (unsigned int i = 0; i < nameLength; ++i)
       
    42          if (name[i] == '.')
       
    43              nd++;
       
    44  
       
    45 -    if (Config.onoff.res_defnames && npc > 0 && name[strlen(name)-1] != '.') {
       
    46 +    if (Config.onoff.res_defnames && npc > 0 && name[nameLength-1] != '.') {
       
    47          q->do_searchpath = 1;
       
    48      } else {
       
    49          q->do_searchpath = 0;