mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-06-08 03:49:57 +00:00
squid: Fix build with gcc8
Signed-off-by: Khem Raj <raj.khem@gmail.com>
This commit is contained in:
+506
@@ -0,0 +1,506 @@
|
|||||||
|
From 01a44c96dbd04936e9cb2501745a834a0b09d504 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Amos Jeffries <yadij@users.noreply.github.com>
|
||||||
|
Date: Sun, 13 May 2018 06:57:41 +0000
|
||||||
|
Subject: [PATCH] Bug 4843 pt1: ext_edirectory_userip_acl refactoring for GCC-8
|
||||||
|
(#204)
|
||||||
|
|
||||||
|
Proposed changes to this helper to fix strcat / strncat buffer
|
||||||
|
overread / overflow issues.
|
||||||
|
|
||||||
|
The approach takes three parts:
|
||||||
|
|
||||||
|
* adds a makeHexString function to replace many for-loops
|
||||||
|
catenating bits of strings together with hex conversion into a
|
||||||
|
second buffer. Replacing with a snprintf() and buffer overflow
|
||||||
|
handling.
|
||||||
|
|
||||||
|
* a copy of Ip::Address::lookupHostIp to convert the input
|
||||||
|
string into IP address binary format, then generate the hex
|
||||||
|
string using the above new hex function instead of looped
|
||||||
|
sub-string concatenations across several buffers.
|
||||||
|
This removes all the "00" and "0000" strncat() calls and
|
||||||
|
allows far simpler code even with added buffer overflow
|
||||||
|
handling.
|
||||||
|
|
||||||
|
* replace multiple string part concatenations with a few simpler
|
||||||
|
calls to snprintf() for all the search_ip buffer constructions.
|
||||||
|
Adding buffer overflow handling as needed for the new calls.
|
||||||
|
---
|
||||||
|
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||||
|
Upstream-Status: Backport
|
||||||
|
|
||||||
|
.../ext_edirectory_userip_acl.cc | 376 ++++++------------
|
||||||
|
1 file changed, 120 insertions(+), 256 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc b/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc
|
||||||
|
index 63609e4..ad16bfd 100644
|
||||||
|
--- a/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc
|
||||||
|
+++ b/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc
|
||||||
|
@@ -67,6 +67,9 @@
|
||||||
|
#ifdef HAVE_LDAP_H
|
||||||
|
#include <ldap.h>
|
||||||
|
#endif
|
||||||
|
+#ifdef HAVE_NETDB_H
|
||||||
|
+#include <netdb.h>
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#ifdef HELPER_INPUT_BUFFER
|
||||||
|
#define EDUI_MAXLEN HELPER_INPUT_BUFFER
|
||||||
|
@@ -714,11 +717,14 @@ BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t)
|
||||||
|
|
||||||
|
/* Copy details - dn and pw CAN be NULL for anonymous and/or TLS */
|
||||||
|
if (dn != NULL) {
|
||||||
|
+ if (strlen(dn) >= sizeof(l->dn))
|
||||||
|
+ return LDAP_ERR_OOB; /* DN too large */
|
||||||
|
+
|
||||||
|
if ((l->basedn[0] != '\0') && (strstr(dn, l->basedn) == NULL)) {
|
||||||
|
/* We got a basedn, but it's not part of dn */
|
||||||
|
- xstrncpy(l->dn, dn, sizeof(l->dn));
|
||||||
|
- strncat(l->dn, ",", 1);
|
||||||
|
- strncat(l->dn, l->basedn, strlen(l->basedn));
|
||||||
|
+ const int x = snprintf(l->dn, sizeof(l->dn)-1, "%s,%s", dn, l->basedn);
|
||||||
|
+ if (x < 0 || static_cast<size_t>(x) >= sizeof(l->dn))
|
||||||
|
+ return LDAP_ERR_OOB; /* DN too large */
|
||||||
|
} else
|
||||||
|
xstrncpy(l->dn, dn, sizeof(l->dn));
|
||||||
|
}
|
||||||
|
@@ -778,24 +784,73 @@ BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+// XXX: duplicate (partial) of Ip::Address::lookupHostIp
|
||||||
|
+/**
|
||||||
|
+ * Convert the IP address string representation in src to
|
||||||
|
+ * its binary representation.
|
||||||
|
+ *
|
||||||
|
+ * \return binary representation of the src IP address.
|
||||||
|
+ * Must be free'd using freeaddrinfo().
|
||||||
|
+ */
|
||||||
|
+static struct addrinfo *
|
||||||
|
+makeIpBinary(const char *src)
|
||||||
|
+{
|
||||||
|
+ struct addrinfo want;
|
||||||
|
+ memset(&want, 0, sizeof(want));
|
||||||
|
+ want.ai_flags = AI_NUMERICHOST; // prevent actual DNS lookups!
|
||||||
|
+
|
||||||
|
+ struct addrinfo *dst = nullptr;
|
||||||
|
+ if (getaddrinfo(src, nullptr, &want, &dst) != 0) {
|
||||||
|
+ // not an IP address
|
||||||
|
+ /* free any memory getaddrinfo() dynamically allocated. */
|
||||||
|
+ if (dst)
|
||||||
|
+ freeaddrinfo(dst);
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return dst;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Convert srcLen bytes from src into HEX and store into dst, which
|
||||||
|
+ * has a maximum content size of dstSize including c-string terminator.
|
||||||
|
+ * The dst value produced will be a 0-terminated c-string.
|
||||||
|
+ *
|
||||||
|
+ * \retval N length of dst written (excluding c-string terminator)
|
||||||
|
+ * \retval -11 (LDAP_ERR_OOB) buffer overflow detected
|
||||||
|
+ */
|
||||||
|
+static int
|
||||||
|
+makeHexString(char *dst, const int dstSize, const char *src, const int srcLen)
|
||||||
|
+{
|
||||||
|
+ // HEX encoding doubles the amount of bytes/octets copied
|
||||||
|
+ if ((srcLen*2) >= dstSize)
|
||||||
|
+ return LDAP_ERR_OOB; // cannot copy that many
|
||||||
|
+
|
||||||
|
+ *dst = 0;
|
||||||
|
+
|
||||||
|
+ for (int k = 0; k < srcLen; ++k) {
|
||||||
|
+ int c = static_cast<int>(src[k]);
|
||||||
|
+ if (c < 0)
|
||||||
|
+ c = c + 256;
|
||||||
|
+ char hexc[4];
|
||||||
|
+ const int hlen = snprintf(hexc, sizeof(hexc), "%02X", c);
|
||||||
|
+ if (hlen < 0 || static_cast<size_t>(hlen) > sizeof(hexc)) // should be impossible
|
||||||
|
+ return LDAP_ERR_OOB;
|
||||||
|
+ strcat(dst, hexc);
|
||||||
|
+ }
|
||||||
|
+ return strlen(dst);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* ConvertIP() - <edui_ldap_t> <ip>
|
||||||
|
*
|
||||||
|
* Take an IPv4 address in dot-decimal or IPv6 notation, and convert to 2-digit HEX stored in l->search_ip
|
||||||
|
* This is the networkAddress that we search LDAP for.
|
||||||
|
- *
|
||||||
|
- * PENDING -- CHANGE OVER TO inet*_pton, but inet6_pton does not provide the correct syntax
|
||||||
|
- *
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ConvertIP(edui_ldap_t *l, char *ip)
|
||||||
|
{
|
||||||
|
- char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], obj[EDUI_MAXLEN];
|
||||||
|
- char hexc[4], *p;
|
||||||
|
void *y, *z;
|
||||||
|
- size_t s;
|
||||||
|
- long x;
|
||||||
|
- int i, j, t, swi; /* IPv6 "::" cut over toggle */
|
||||||
|
if (l == NULL) return LDAP_ERR_NULL;
|
||||||
|
if (ip == NULL) return LDAP_ERR_PARAM;
|
||||||
|
if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */
|
||||||
|
@@ -831,183 +886,22 @@ ConvertIP(edui_ldap_t *l, char *ip)
|
||||||
|
l->status |= (LDAP_IPV4_S);
|
||||||
|
z = NULL;
|
||||||
|
}
|
||||||
|
- s = strlen(ip);
|
||||||
|
- *(bufa) = '\0';
|
||||||
|
- *(bufb) = '\0';
|
||||||
|
- *(obj) = '\0';
|
||||||
|
- /* StringSplit() will zero out bufa & obj at each call */
|
||||||
|
- memset(l->search_ip, '\0', sizeof(l->search_ip));
|
||||||
|
- xstrncpy(bufa, ip, sizeof(bufa)); /* To avoid segfaults, use bufa instead of ip */
|
||||||
|
- swi = 0;
|
||||||
|
- if (l->status & LDAP_IPV6_S) {
|
||||||
|
- /* Search for :: in string */
|
||||||
|
- if ((bufa[0] == ':') && (bufa[1] == ':')) {
|
||||||
|
- /* bufa starts with a ::, so just copy and clear */
|
||||||
|
- xstrncpy(bufb, bufa, sizeof(bufb));
|
||||||
|
- *(bufa) = '\0';
|
||||||
|
- ++swi; /* Indicates that there is a bufb */
|
||||||
|
- } else if ((bufa[0] == ':') && (bufa[1] != ':')) {
|
||||||
|
- /* bufa starts with a :, a typo so just fill in a ':', cat and clear */
|
||||||
|
- bufb[0] = ':';
|
||||||
|
- strncat(bufb, bufa, strlen(bufa));
|
||||||
|
- *(bufa) = '\0';
|
||||||
|
- ++swi; /* Indicates that there is a bufb */
|
||||||
|
- } else {
|
||||||
|
- p = strstr(bufa, "::");
|
||||||
|
- if (p != NULL) {
|
||||||
|
- /* Found it, break bufa down and split into bufb here */
|
||||||
|
- *(bufb) = '\0';
|
||||||
|
- i = strlen(p);
|
||||||
|
- memcpy(bufb, p, i);
|
||||||
|
- *p = '\0';
|
||||||
|
- bufb[i] = '\0';
|
||||||
|
- ++swi; /* Indicates that there is a bufb */
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- s = strlen(bufa);
|
||||||
|
- if (s < 1)
|
||||||
|
- s = strlen(bufb);
|
||||||
|
- while (s > 0) {
|
||||||
|
- if ((l->status & LDAP_IPV4_S) && (swi == 0)) {
|
||||||
|
- /* Break down IPv4 address */
|
||||||
|
- t = StringSplit(bufa, '.', obj, sizeof(obj));
|
||||||
|
- if (t > 0) {
|
||||||
|
- errno = 0;
|
||||||
|
- x = strtol(obj, (char **)NULL, 10);
|
||||||
|
- if (((x < 0) || (x > 255)) || ((errno != 0) && (x == 0)) || ((obj[0] != '0') && (x == 0)))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds -- Invalid address */
|
||||||
|
- memset(hexc, '\0', sizeof(hexc));
|
||||||
|
- int hlen = snprintf(hexc, sizeof(hexc), "%02X", (int)x);
|
||||||
|
- strncat(l->search_ip, hexc, hlen);
|
||||||
|
- } else
|
||||||
|
- break; /* reached end of octet */
|
||||||
|
- } else if (l->status & LDAP_IPV6_S) {
|
||||||
|
- /* Break down IPv6 address */
|
||||||
|
- if (swi > 1)
|
||||||
|
- t = StringSplit(bufb, ':', obj, sizeof(obj)); /* After "::" */
|
||||||
|
- else
|
||||||
|
- t = StringSplit(bufa, ':', obj, sizeof(obj)); /* Before "::" */
|
||||||
|
- /* Convert octet by size (t) - and fill 0's */
|
||||||
|
- switch (t) { /* IPv6 is already in HEX, copy contents */
|
||||||
|
- case 4:
|
||||||
|
- hexc[0] = (char) toupper((int)obj[0]);
|
||||||
|
- i = (int)hexc[0];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[1] = (char) toupper((int)obj[1]);
|
||||||
|
- i = (int)hexc[1];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[2] = '\0';
|
||||||
|
- strncat(l->search_ip, hexc, 2);
|
||||||
|
- hexc[0] = (char) toupper((int)obj[2]);
|
||||||
|
- i = (int)hexc[0];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[1] = (char) toupper((int)obj[3]);
|
||||||
|
- i = (int)hexc[1];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[2] = '\0';
|
||||||
|
- strncat(l->search_ip, hexc, 2);
|
||||||
|
- break;
|
||||||
|
- case 3:
|
||||||
|
- hexc[0] = '0';
|
||||||
|
- hexc[1] = (char) toupper((int)obj[0]);
|
||||||
|
- i = (int)hexc[1];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[2] = '\0';
|
||||||
|
- strncat(l->search_ip, hexc, 2);
|
||||||
|
- hexc[0] = (char) toupper((int)obj[1]);
|
||||||
|
- i = (int)hexc[0];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[1] = (char) toupper((int)obj[2]);
|
||||||
|
- i = (int)hexc[1];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[2] = '\0';
|
||||||
|
- strncat(l->search_ip, hexc, 2);
|
||||||
|
- break;
|
||||||
|
- case 2:
|
||||||
|
- strncat(l->search_ip, "00", 2);
|
||||||
|
- hexc[0] = (char) toupper((int)obj[0]);
|
||||||
|
- i = (int)hexc[0];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[1] = (char) toupper((int)obj[1]);
|
||||||
|
- i = (int)hexc[1];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[2] = '\0';
|
||||||
|
- strncat(l->search_ip, hexc, 2);
|
||||||
|
- break;
|
||||||
|
- case 1:
|
||||||
|
- strncat(l->search_ip, "00", 2);
|
||||||
|
- hexc[0] = '0';
|
||||||
|
- hexc[1] = (char) toupper((int)obj[0]);
|
||||||
|
- i = (int)hexc[1];
|
||||||
|
- if (!isxdigit(i))
|
||||||
|
- return LDAP_ERR_OOB; /* Out of bounds */
|
||||||
|
- hexc[2] = '\0';
|
||||||
|
- strncat(l->search_ip, hexc, 2);
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- if (t > 4)
|
||||||
|
- return LDAP_ERR_OOB;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- /* Code to pad the address with 0's between a '::' */
|
||||||
|
- if ((strlen(bufa) == 0) && (swi == 1)) {
|
||||||
|
- /* We are *AT* the split, pad in some 0000 */
|
||||||
|
- t = strlen(bufb);
|
||||||
|
- /* How many ':' exist in bufb ? */
|
||||||
|
- j = 0;
|
||||||
|
- for (i = 0; i < t; ++i) {
|
||||||
|
- if (bufb[i] == ':')
|
||||||
|
- ++j;
|
||||||
|
- }
|
||||||
|
- --j; /* Preceding "::" doesn't count */
|
||||||
|
- t = 8 - (strlen(l->search_ip) / 4) - j; /* Remainder */
|
||||||
|
- if (t > 0) {
|
||||||
|
- for (i = 0; i < t; ++i)
|
||||||
|
- strncat(l->search_ip, "0000", 4);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if ((bufa[0] == '\0') && (swi > 0)) {
|
||||||
|
- s = strlen(bufb);
|
||||||
|
- ++swi;
|
||||||
|
- } else
|
||||||
|
- s = strlen(bufa);
|
||||||
|
- }
|
||||||
|
- s = strlen(l->search_ip);
|
||||||
|
|
||||||
|
- /* CHECK sizes of address, truncate or pad */
|
||||||
|
- /* if "::" is at end of ip, then pad another block or two */
|
||||||
|
- while ((l->status & LDAP_IPV6_S) && (s < 32)) {
|
||||||
|
- strncat(l->search_ip, "0000", 4);
|
||||||
|
- s = strlen(l->search_ip);
|
||||||
|
- }
|
||||||
|
- if ((l->status & LDAP_IPV6_S) && (s > 32)) {
|
||||||
|
- /* Too long, truncate */
|
||||||
|
- l->search_ip[32] = '\0';
|
||||||
|
- s = strlen(l->search_ip);
|
||||||
|
- }
|
||||||
|
- /* If at end of ip, and its not long enough, then pad another block or two */
|
||||||
|
- while ((l->status & LDAP_IPV4_S) && (s < 8)) {
|
||||||
|
- strncat(l->search_ip, "00", 2);
|
||||||
|
- s = strlen(l->search_ip);
|
||||||
|
- }
|
||||||
|
- if ((l->status & LDAP_IPV4_S) && (s > 8)) {
|
||||||
|
- /* Too long, truncate */
|
||||||
|
- l->search_ip[8] = '\0';
|
||||||
|
- s = strlen(l->search_ip);
|
||||||
|
+ size_t s = LDAP_ERR_INVALID;
|
||||||
|
+ if (struct addrinfo *dst = makeIpBinary(ip)) {
|
||||||
|
+ if (dst->ai_family == AF_INET6) {
|
||||||
|
+ struct sockaddr_in6 *sia = reinterpret_cast<struct sockaddr_in6 *>(dst->ai_addr);
|
||||||
|
+ const char *ia = reinterpret_cast<const char *>(sia->sin6_addr.s6_addr);
|
||||||
|
+ s = makeHexString(l->search_ip, sizeof(l->search_ip), ia, 16); // IPv6 = 16-byte address
|
||||||
|
+
|
||||||
|
+ } else if (dst->ai_family == AF_INET) {
|
||||||
|
+ struct sockaddr_in *sia = reinterpret_cast<struct sockaddr_in *>(dst->ai_addr);
|
||||||
|
+ const char *ia = reinterpret_cast<const char *>(&(sia->sin_addr));
|
||||||
|
+ s = makeHexString(l->search_ip, sizeof(l->search_ip), ia, 4); // IPv4 = 4-byte address
|
||||||
|
+ } // else leave s with LDAP_ERR_INVALID value
|
||||||
|
+ freeaddrinfo(dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Completed, s is length of address in HEX */
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1099,48 +993,42 @@ SearchFilterLDAP(edui_ldap_t *l, char *group)
|
||||||
|
}
|
||||||
|
if (group == NULL) {
|
||||||
|
/* No groupMembership= to add, yay! */
|
||||||
|
- xstrncpy(bufa, "(&", sizeof(bufa));
|
||||||
|
- strncat(bufa, edui_conf.search_filter, strlen(edui_conf.search_filter));
|
||||||
|
/* networkAddress */
|
||||||
|
- snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)", bufc);
|
||||||
|
if (l->status & LDAP_IPV4_S) {
|
||||||
|
- int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s))", \
|
||||||
|
- bufc, bufc);
|
||||||
|
- strncat(bufb, bufd, ln);
|
||||||
|
+ const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", bufc, bufc);
|
||||||
|
+ if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd))
|
||||||
|
+ return LDAP_ERR_OOB;
|
||||||
|
+
|
||||||
|
} else if (l->status & LDAP_IPV6_S) {
|
||||||
|
- int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \
|
||||||
|
- bufc, bufc);
|
||||||
|
- strncat(bufb, bufd, ln);
|
||||||
|
- } else
|
||||||
|
- strncat(bufb, ")", 1);
|
||||||
|
- strncat(bufa, bufb, strlen(bufb));
|
||||||
|
- strncat(bufa, ")", 1);
|
||||||
|
+ const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s)", bufc, bufc);
|
||||||
|
+ if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd))
|
||||||
|
+ return LDAP_ERR_OOB;
|
||||||
|
+ }
|
||||||
|
+ const int x = snprintf(bufa, sizeof(bufa), "(&%s(|(networkAddress=1\\23%s)%s))", edui_conf.search_filter, bufc, bufd);
|
||||||
|
+ if (x < 0 || static_cast<size_t>(x) >= sizeof(bufa))
|
||||||
|
+ return LDAP_ERR_OOB;
|
||||||
|
+
|
||||||
|
} else {
|
||||||
|
/* Needs groupMembership= to add... */
|
||||||
|
- xstrncpy(bufa, "(&(&", sizeof(bufa));
|
||||||
|
- strncat(bufa, edui_conf.search_filter, strlen(edui_conf.search_filter));
|
||||||
|
/* groupMembership -- NOTE: Squid *MUST* provide "cn=" from squid.conf */
|
||||||
|
- snprintf(bufg, sizeof(bufg), "(groupMembership=%s", group);
|
||||||
|
if ((l->basedn[0] != '\0') && (strstr(group, l->basedn) == NULL)) {
|
||||||
|
- strncat(bufg, ",", 1);
|
||||||
|
- strncat(bufg, l->basedn, strlen(l->basedn));
|
||||||
|
+ const int ln = snprintf(bufg, sizeof(bufg), ",%s", l->basedn);
|
||||||
|
+ if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd))
|
||||||
|
+ return LDAP_ERR_OOB;
|
||||||
|
}
|
||||||
|
- strncat(bufg, ")", 1);
|
||||||
|
- strncat(bufa, bufg, strlen(bufg));
|
||||||
|
/* networkAddress */
|
||||||
|
- snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)", bufc);
|
||||||
|
if (l->status & LDAP_IPV4_S) {
|
||||||
|
- int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s))", \
|
||||||
|
- bufc, bufc);
|
||||||
|
- strncat(bufb, bufd, ln);
|
||||||
|
+ const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", bufc, bufc);
|
||||||
|
+ if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd))
|
||||||
|
+ return LDAP_ERR_OOB;
|
||||||
|
} else if (l->status & LDAP_IPV6_S) {
|
||||||
|
- int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \
|
||||||
|
- bufc, bufc);
|
||||||
|
- strncat(bufb, bufd, ln);
|
||||||
|
- } else
|
||||||
|
- strncat(bufb, ")", 1);
|
||||||
|
- strncat(bufa, bufb, strlen(bufb));
|
||||||
|
- strncat(bufa, "))", 2);
|
||||||
|
+ const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s)", bufc, bufc);
|
||||||
|
+ if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd))
|
||||||
|
+ return LDAP_ERR_OOB;
|
||||||
|
+ }
|
||||||
|
+ const int x = snprintf(bufa, sizeof(bufa), "(&(&%s(groupMembership=%s%s)(|(networkAddress=1\\23%s)%s)))", edui_conf.search_filter, group, bufg, bufc, bufd);
|
||||||
|
+ if (x < 0 || static_cast<size_t>(x) >= sizeof(bufa))
|
||||||
|
+ return LDAP_ERR_OOB;
|
||||||
|
}
|
||||||
|
s = strlen(bufa);
|
||||||
|
xstrncpy(l->search_filter, bufa, sizeof(l->search_filter));
|
||||||
|
@@ -1212,10 +1100,10 @@ static int
|
||||||
|
SearchIPLDAP(edui_ldap_t *l)
|
||||||
|
{
|
||||||
|
ber_len_t i, x;
|
||||||
|
- ber_len_t j, k;
|
||||||
|
- ber_len_t y, z;
|
||||||
|
- int c;
|
||||||
|
- char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], hexc[4];
|
||||||
|
+ ber_len_t j;
|
||||||
|
+ ber_len_t z;
|
||||||
|
+ char bufa[EDUI_MAXLEN];
|
||||||
|
+ char bufb[EDUI_MAXLEN];
|
||||||
|
LDAPMessage *ent;
|
||||||
|
if (l == NULL) return LDAP_ERR_NULL;
|
||||||
|
if (l->lp == NULL) return LDAP_ERR_POINTER;
|
||||||
|
@@ -1273,19 +1161,11 @@ SearchIPLDAP(edui_ldap_t *l)
|
||||||
|
/* bufa is the address, just compare it */
|
||||||
|
if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S))
|
||||||
|
break; /* Not looking for IPv4 */
|
||||||
|
- for (k = 0; k < z; ++k) {
|
||||||
|
- c = (int) bufa[k];
|
||||||
|
- if (c < 0)
|
||||||
|
- c = c + 256;
|
||||||
|
- int hlen = snprintf(hexc, sizeof(hexc), "%02X", c);
|
||||||
|
- if (k == 0)
|
||||||
|
- xstrncpy(bufb, hexc, sizeof(bufb));
|
||||||
|
- else
|
||||||
|
- strncat(bufb, hexc, hlen);
|
||||||
|
- }
|
||||||
|
- y = strlen(bufb);
|
||||||
|
+ const int blen = makeHexString(bufb, sizeof(bufb), bufa, z);
|
||||||
|
+ if (blen < 0)
|
||||||
|
+ return blen;
|
||||||
|
/* Compare value with IP */
|
||||||
|
- if (memcmp(l->search_ip, bufb, y) == 0) {
|
||||||
|
+ if (memcmp(l->search_ip, bufb, blen) == 0) {
|
||||||
|
/* We got a match! - Scan 'ber' for 'cn' values */
|
||||||
|
z = ldap_count_values_len(ber);
|
||||||
|
for (j = 0; j < z; ++j) {
|
||||||
|
@@ -1308,19 +1188,11 @@ SearchIPLDAP(edui_ldap_t *l)
|
||||||
|
/* bufa + 2 is the address (skip 2 digit port) */
|
||||||
|
if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S))
|
||||||
|
break; /* Not looking for IPv4 */
|
||||||
|
- for (k = 2; k < z; ++k) {
|
||||||
|
- c = (int) bufa[k];
|
||||||
|
- if (c < 0)
|
||||||
|
- c = c + 256;
|
||||||
|
- int hlen = snprintf(hexc, sizeof(hexc), "%02X", c);
|
||||||
|
- if (k == 2)
|
||||||
|
- xstrncpy(bufb, hexc, sizeof(bufb));
|
||||||
|
- else
|
||||||
|
- strncat(bufb, hexc, hlen);
|
||||||
|
- }
|
||||||
|
- y = strlen(bufb);
|
||||||
|
+ const int blen = makeHexString(bufb, sizeof(bufb), &bufa[2], z);
|
||||||
|
+ if (blen < 0)
|
||||||
|
+ return blen;
|
||||||
|
/* Compare value with IP */
|
||||||
|
- if (memcmp(l->search_ip, bufb, y) == 0) {
|
||||||
|
+ if (memcmp(l->search_ip, bufb, blen) == 0) {
|
||||||
|
/* We got a match! - Scan 'ber' for 'cn' values */
|
||||||
|
z = ldap_count_values_len(ber);
|
||||||
|
for (j = 0; j < z; ++j) {
|
||||||
|
@@ -1343,19 +1215,11 @@ SearchIPLDAP(edui_ldap_t *l)
|
||||||
|
/* bufa + 2 is the address (skip 2 digit port) */
|
||||||
|
if (!(l->status & LDAP_IPV6_S))
|
||||||
|
break; /* Not looking for IPv6 */
|
||||||
|
- for (k = 2; k < z; ++k) {
|
||||||
|
- c = (int) bufa[k];
|
||||||
|
- if (c < 0)
|
||||||
|
- c = c + 256;
|
||||||
|
- int hlen = snprintf(hexc, sizeof(hexc), "%02X", c);
|
||||||
|
- if (k == 2)
|
||||||
|
- xstrncpy(bufb, hexc, sizeof(bufb));
|
||||||
|
- else
|
||||||
|
- strncat(bufb, hexc, hlen);
|
||||||
|
- }
|
||||||
|
- y = strlen(bufb);
|
||||||
|
+ const int blen = makeHexString(bufb, sizeof(bufb), &bufa[2], z);
|
||||||
|
+ if (blen < 0)
|
||||||
|
+ return blen;
|
||||||
|
/* Compare value with IP */
|
||||||
|
- if (memcmp(l->search_ip, bufb, y) == 0) {
|
||||||
|
+ if (memcmp(l->search_ip, bufb, blen) == 0) {
|
||||||
|
/* We got a match! - Scan 'ber' for 'cn' values */
|
||||||
|
z = ldap_count_values_len(ber);
|
||||||
|
for (j = 0; j < z; ++j) {
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
From a6b1e0fd14311587186e40d09bff5c8c3aada2e4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Amos Jeffries <squid3@treenet.co.nz>
|
||||||
|
Date: Sat, 25 Jul 2015 05:53:16 -0700
|
||||||
|
Subject: [PATCH] smblib: fix buffer over-read
|
||||||
|
|
||||||
|
When parsing SMB LanManager packets with invalid protocol ID and the
|
||||||
|
default set of Squid supported protocols. It may access memory outside
|
||||||
|
the buffer storing protocol names.
|
||||||
|
|
||||||
|
smblib is only used by already deprecated helpers which are deprecated
|
||||||
|
due to far more significant NTLM protocol issues. It will also only
|
||||||
|
result in packets being rejected later with invalid protocol names. So
|
||||||
|
this is a minor bug rather than a vulnerability.
|
||||||
|
|
||||||
|
Detected by Coverity Scan. Issue 1256165
|
||||||
|
---
|
||||||
|
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||||
|
Upstream-Status: Backport
|
||||||
|
|
||||||
|
lib/smblib/smblib-util.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/smblib/smblib-util.c b/lib/smblib/smblib-util.c
|
||||||
|
index 6139ae2..e722cbb 100644
|
||||||
|
--- a/lib/smblib/smblib-util.c
|
||||||
|
+++ b/lib/smblib/smblib-util.c
|
||||||
|
@@ -204,7 +204,11 @@ int SMB_Figure_Protocol(const char *dialects[], int prot_index)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- if (dialects == SMB_Prots) { /* The jobs is easy, just index into table */
|
||||||
|
+ // prot_index may be a value outside the table SMB_Types[]
|
||||||
|
+ // which holds data at offsets 0 to 11
|
||||||
|
+ int ourType = (prot_index < 0 || prot_index > 11);
|
||||||
|
+
|
||||||
|
+ if (ourType && dialects == SMB_Prots) { /* The jobs is easy, just index into table */
|
||||||
|
|
||||||
|
return(SMB_Types[prot_index]);
|
||||||
|
} else { /* Search through SMB_Prots looking for a match */
|
||||||
@@ -23,6 +23,8 @@ SRC_URI = "http://www.squid-cache.org/Versions/v${MAJ_VER}/${MIN_VER}/${BPN}-${P
|
|||||||
file://squid-don-t-do-squid-conf-tests-at-build-time.patch \
|
file://squid-don-t-do-squid-conf-tests-at-build-time.patch \
|
||||||
file://0001-configure-Check-for-Wno-error-format-truncation-comp.patch \
|
file://0001-configure-Check-for-Wno-error-format-truncation-comp.patch \
|
||||||
file://0001-tools.cc-fixed-unused-result-warning.patch \
|
file://0001-tools.cc-fixed-unused-result-warning.patch \
|
||||||
|
file://0001-Bug-4843-pt1-ext_edirectory_userip_acl-refactoring-f.patch \
|
||||||
|
file://0002-smblib-fix-buffer-over-read.patch \
|
||||||
"
|
"
|
||||||
|
|
||||||
SRC_URI_remove_toolchain-clang = "file://0001-configure-Check-for-Wno-error-format-truncation-comp.patch"
|
SRC_URI_remove_toolchain-clang = "file://0001-configure-Check-for-Wno-error-format-truncation-comp.patch"
|
||||||
@@ -48,6 +50,7 @@ PACKAGECONFIG ??= "${@bb.utils.contains('TARGET_ARCH', 'powerpc', 'noatomics', '
|
|||||||
PACKAGECONFIG[libnetfilter-conntrack] = "--with-netfilter-conntrack=${includedir}, --without-netfilter-conntrack, libnetfilter-conntrack"
|
PACKAGECONFIG[libnetfilter-conntrack] = "--with-netfilter-conntrack=${includedir}, --without-netfilter-conntrack, libnetfilter-conntrack"
|
||||||
PACKAGECONFIG[noatomics] = "squid_cv_gnu_atomics=no,squid_cv_gnu_atomics=yes,,"
|
PACKAGECONFIG[noatomics] = "squid_cv_gnu_atomics=no,squid_cv_gnu_atomics=yes,,"
|
||||||
PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6,"
|
PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6,"
|
||||||
|
PACKAGECONFIG[werror] = "--enable-strict-error-checking,--disable-strict-error-checking,"
|
||||||
|
|
||||||
BASIC_AUTH = "DB SASL LDAP"
|
BASIC_AUTH = "DB SASL LDAP"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user