diff options
3 files changed, 548 insertions, 0 deletions
diff --git a/meta-networking/recipes-daemons/squid/files/0001-Bug-4843-pt1-ext_edirectory_userip_acl-refactoring-f.patch b/meta-networking/recipes-daemons/squid/files/0001-Bug-4843-pt1-ext_edirectory_userip_acl-refactoring-f.patch new file mode 100644 index 0000000000..001d9e906e --- /dev/null +++ b/meta-networking/recipes-daemons/squid/files/0001-Bug-4843-pt1-ext_edirectory_userip_acl-refactoring-f.patch | |||
| @@ -0,0 +1,506 @@ | |||
| 1 | From 01a44c96dbd04936e9cb2501745a834a0b09d504 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Amos Jeffries <yadij@users.noreply.github.com> | ||
| 3 | Date: Sun, 13 May 2018 06:57:41 +0000 | ||
| 4 | Subject: [PATCH] Bug 4843 pt1: ext_edirectory_userip_acl refactoring for GCC-8 | ||
| 5 | (#204) | ||
| 6 | |||
| 7 | Proposed changes to this helper to fix strcat / strncat buffer | ||
| 8 | overread / overflow issues. | ||
| 9 | |||
| 10 | The approach takes three parts: | ||
| 11 | |||
| 12 | * adds a makeHexString function to replace many for-loops | ||
| 13 | catenating bits of strings together with hex conversion into a | ||
| 14 | second buffer. Replacing with a snprintf() and buffer overflow | ||
| 15 | handling. | ||
| 16 | |||
| 17 | * a copy of Ip::Address::lookupHostIp to convert the input | ||
| 18 | string into IP address binary format, then generate the hex | ||
| 19 | string using the above new hex function instead of looped | ||
| 20 | sub-string concatenations across several buffers. | ||
| 21 | This removes all the "00" and "0000" strncat() calls and | ||
| 22 | allows far simpler code even with added buffer overflow | ||
| 23 | handling. | ||
| 24 | |||
| 25 | * replace multiple string part concatenations with a few simpler | ||
| 26 | calls to snprintf() for all the search_ip buffer constructions. | ||
| 27 | Adding buffer overflow handling as needed for the new calls. | ||
| 28 | --- | ||
| 29 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
| 30 | Upstream-Status: Backport | ||
| 31 | |||
| 32 | .../ext_edirectory_userip_acl.cc | 376 ++++++------------ | ||
| 33 | 1 file changed, 120 insertions(+), 256 deletions(-) | ||
| 34 | |||
| 35 | diff --git a/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc b/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc | ||
| 36 | index 63609e4..ad16bfd 100644 | ||
| 37 | --- a/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc | ||
| 38 | +++ b/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc | ||
| 39 | @@ -67,6 +67,9 @@ | ||
| 40 | #ifdef HAVE_LDAP_H | ||
| 41 | #include <ldap.h> | ||
| 42 | #endif | ||
| 43 | +#ifdef HAVE_NETDB_H | ||
| 44 | +#include <netdb.h> | ||
| 45 | +#endif | ||
| 46 | |||
| 47 | #ifdef HELPER_INPUT_BUFFER | ||
| 48 | #define EDUI_MAXLEN HELPER_INPUT_BUFFER | ||
| 49 | @@ -714,11 +717,14 @@ BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t) | ||
| 50 | |||
| 51 | /* Copy details - dn and pw CAN be NULL for anonymous and/or TLS */ | ||
| 52 | if (dn != NULL) { | ||
| 53 | + if (strlen(dn) >= sizeof(l->dn)) | ||
| 54 | + return LDAP_ERR_OOB; /* DN too large */ | ||
| 55 | + | ||
| 56 | if ((l->basedn[0] != '\0') && (strstr(dn, l->basedn) == NULL)) { | ||
| 57 | /* We got a basedn, but it's not part of dn */ | ||
| 58 | - xstrncpy(l->dn, dn, sizeof(l->dn)); | ||
| 59 | - strncat(l->dn, ",", 1); | ||
| 60 | - strncat(l->dn, l->basedn, strlen(l->basedn)); | ||
| 61 | + const int x = snprintf(l->dn, sizeof(l->dn)-1, "%s,%s", dn, l->basedn); | ||
| 62 | + if (x < 0 || static_cast<size_t>(x) >= sizeof(l->dn)) | ||
| 63 | + return LDAP_ERR_OOB; /* DN too large */ | ||
| 64 | } else | ||
| 65 | xstrncpy(l->dn, dn, sizeof(l->dn)); | ||
| 66 | } | ||
| 67 | @@ -778,24 +784,73 @@ BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t) | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | +// XXX: duplicate (partial) of Ip::Address::lookupHostIp | ||
| 72 | +/** | ||
| 73 | + * Convert the IP address string representation in src to | ||
| 74 | + * its binary representation. | ||
| 75 | + * | ||
| 76 | + * \return binary representation of the src IP address. | ||
| 77 | + * Must be free'd using freeaddrinfo(). | ||
| 78 | + */ | ||
| 79 | +static struct addrinfo * | ||
| 80 | +makeIpBinary(const char *src) | ||
| 81 | +{ | ||
| 82 | + struct addrinfo want; | ||
| 83 | + memset(&want, 0, sizeof(want)); | ||
| 84 | + want.ai_flags = AI_NUMERICHOST; // prevent actual DNS lookups! | ||
| 85 | + | ||
| 86 | + struct addrinfo *dst = nullptr; | ||
| 87 | + if (getaddrinfo(src, nullptr, &want, &dst) != 0) { | ||
| 88 | + // not an IP address | ||
| 89 | + /* free any memory getaddrinfo() dynamically allocated. */ | ||
| 90 | + if (dst) | ||
| 91 | + freeaddrinfo(dst); | ||
| 92 | + return nullptr; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + return dst; | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +/** | ||
| 99 | + * Convert srcLen bytes from src into HEX and store into dst, which | ||
| 100 | + * has a maximum content size of dstSize including c-string terminator. | ||
| 101 | + * The dst value produced will be a 0-terminated c-string. | ||
| 102 | + * | ||
| 103 | + * \retval N length of dst written (excluding c-string terminator) | ||
| 104 | + * \retval -11 (LDAP_ERR_OOB) buffer overflow detected | ||
| 105 | + */ | ||
| 106 | +static int | ||
| 107 | +makeHexString(char *dst, const int dstSize, const char *src, const int srcLen) | ||
| 108 | +{ | ||
| 109 | + // HEX encoding doubles the amount of bytes/octets copied | ||
| 110 | + if ((srcLen*2) >= dstSize) | ||
| 111 | + return LDAP_ERR_OOB; // cannot copy that many | ||
| 112 | + | ||
| 113 | + *dst = 0; | ||
| 114 | + | ||
| 115 | + for (int k = 0; k < srcLen; ++k) { | ||
| 116 | + int c = static_cast<int>(src[k]); | ||
| 117 | + if (c < 0) | ||
| 118 | + c = c + 256; | ||
| 119 | + char hexc[4]; | ||
| 120 | + const int hlen = snprintf(hexc, sizeof(hexc), "%02X", c); | ||
| 121 | + if (hlen < 0 || static_cast<size_t>(hlen) > sizeof(hexc)) // should be impossible | ||
| 122 | + return LDAP_ERR_OOB; | ||
| 123 | + strcat(dst, hexc); | ||
| 124 | + } | ||
| 125 | + return strlen(dst); | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | /* | ||
| 129 | * ConvertIP() - <edui_ldap_t> <ip> | ||
| 130 | * | ||
| 131 | * Take an IPv4 address in dot-decimal or IPv6 notation, and convert to 2-digit HEX stored in l->search_ip | ||
| 132 | * This is the networkAddress that we search LDAP for. | ||
| 133 | - * | ||
| 134 | - * PENDING -- CHANGE OVER TO inet*_pton, but inet6_pton does not provide the correct syntax | ||
| 135 | - * | ||
| 136 | */ | ||
| 137 | static int | ||
| 138 | ConvertIP(edui_ldap_t *l, char *ip) | ||
| 139 | { | ||
| 140 | - char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], obj[EDUI_MAXLEN]; | ||
| 141 | - char hexc[4], *p; | ||
| 142 | void *y, *z; | ||
| 143 | - size_t s; | ||
| 144 | - long x; | ||
| 145 | - int i, j, t, swi; /* IPv6 "::" cut over toggle */ | ||
| 146 | if (l == NULL) return LDAP_ERR_NULL; | ||
| 147 | if (ip == NULL) return LDAP_ERR_PARAM; | ||
| 148 | if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ | ||
| 149 | @@ -831,183 +886,22 @@ ConvertIP(edui_ldap_t *l, char *ip) | ||
| 150 | l->status |= (LDAP_IPV4_S); | ||
| 151 | z = NULL; | ||
| 152 | } | ||
| 153 | - s = strlen(ip); | ||
| 154 | - *(bufa) = '\0'; | ||
| 155 | - *(bufb) = '\0'; | ||
| 156 | - *(obj) = '\0'; | ||
| 157 | - /* StringSplit() will zero out bufa & obj at each call */ | ||
| 158 | - memset(l->search_ip, '\0', sizeof(l->search_ip)); | ||
| 159 | - xstrncpy(bufa, ip, sizeof(bufa)); /* To avoid segfaults, use bufa instead of ip */ | ||
| 160 | - swi = 0; | ||
| 161 | - if (l->status & LDAP_IPV6_S) { | ||
| 162 | - /* Search for :: in string */ | ||
| 163 | - if ((bufa[0] == ':') && (bufa[1] == ':')) { | ||
| 164 | - /* bufa starts with a ::, so just copy and clear */ | ||
| 165 | - xstrncpy(bufb, bufa, sizeof(bufb)); | ||
| 166 | - *(bufa) = '\0'; | ||
| 167 | - ++swi; /* Indicates that there is a bufb */ | ||
| 168 | - } else if ((bufa[0] == ':') && (bufa[1] != ':')) { | ||
| 169 | - /* bufa starts with a :, a typo so just fill in a ':', cat and clear */ | ||
| 170 | - bufb[0] = ':'; | ||
| 171 | - strncat(bufb, bufa, strlen(bufa)); | ||
| 172 | - *(bufa) = '\0'; | ||
| 173 | - ++swi; /* Indicates that there is a bufb */ | ||
| 174 | - } else { | ||
| 175 | - p = strstr(bufa, "::"); | ||
| 176 | - if (p != NULL) { | ||
| 177 | - /* Found it, break bufa down and split into bufb here */ | ||
| 178 | - *(bufb) = '\0'; | ||
| 179 | - i = strlen(p); | ||
| 180 | - memcpy(bufb, p, i); | ||
| 181 | - *p = '\0'; | ||
| 182 | - bufb[i] = '\0'; | ||
| 183 | - ++swi; /* Indicates that there is a bufb */ | ||
| 184 | - } | ||
| 185 | - } | ||
| 186 | - } | ||
| 187 | - s = strlen(bufa); | ||
| 188 | - if (s < 1) | ||
| 189 | - s = strlen(bufb); | ||
| 190 | - while (s > 0) { | ||
| 191 | - if ((l->status & LDAP_IPV4_S) && (swi == 0)) { | ||
| 192 | - /* Break down IPv4 address */ | ||
| 193 | - t = StringSplit(bufa, '.', obj, sizeof(obj)); | ||
| 194 | - if (t > 0) { | ||
| 195 | - errno = 0; | ||
| 196 | - x = strtol(obj, (char **)NULL, 10); | ||
| 197 | - if (((x < 0) || (x > 255)) || ((errno != 0) && (x == 0)) || ((obj[0] != '0') && (x == 0))) | ||
| 198 | - return LDAP_ERR_OOB; /* Out of bounds -- Invalid address */ | ||
| 199 | - memset(hexc, '\0', sizeof(hexc)); | ||
| 200 | - int hlen = snprintf(hexc, sizeof(hexc), "%02X", (int)x); | ||
| 201 | - strncat(l->search_ip, hexc, hlen); | ||
| 202 | - } else | ||
| 203 | - break; /* reached end of octet */ | ||
| 204 | - } else if (l->status & LDAP_IPV6_S) { | ||
| 205 | - /* Break down IPv6 address */ | ||
| 206 | - if (swi > 1) | ||
| 207 | - t = StringSplit(bufb, ':', obj, sizeof(obj)); /* After "::" */ | ||
| 208 | - else | ||
| 209 | - t = StringSplit(bufa, ':', obj, sizeof(obj)); /* Before "::" */ | ||
| 210 | - /* Convert octet by size (t) - and fill 0's */ | ||
| 211 | - switch (t) { /* IPv6 is already in HEX, copy contents */ | ||
| 212 | - case 4: | ||
| 213 | - hexc[0] = (char) toupper((int)obj[0]); | ||
| 214 | - i = (int)hexc[0]; | ||
| 215 | - if (!isxdigit(i)) | ||
| 216 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 217 | - hexc[1] = (char) toupper((int)obj[1]); | ||
| 218 | - i = (int)hexc[1]; | ||
| 219 | - if (!isxdigit(i)) | ||
| 220 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 221 | - hexc[2] = '\0'; | ||
| 222 | - strncat(l->search_ip, hexc, 2); | ||
| 223 | - hexc[0] = (char) toupper((int)obj[2]); | ||
| 224 | - i = (int)hexc[0]; | ||
| 225 | - if (!isxdigit(i)) | ||
| 226 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 227 | - hexc[1] = (char) toupper((int)obj[3]); | ||
| 228 | - i = (int)hexc[1]; | ||
| 229 | - if (!isxdigit(i)) | ||
| 230 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 231 | - hexc[2] = '\0'; | ||
| 232 | - strncat(l->search_ip, hexc, 2); | ||
| 233 | - break; | ||
| 234 | - case 3: | ||
| 235 | - hexc[0] = '0'; | ||
| 236 | - hexc[1] = (char) toupper((int)obj[0]); | ||
| 237 | - i = (int)hexc[1]; | ||
| 238 | - if (!isxdigit(i)) | ||
| 239 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 240 | - hexc[2] = '\0'; | ||
| 241 | - strncat(l->search_ip, hexc, 2); | ||
| 242 | - hexc[0] = (char) toupper((int)obj[1]); | ||
| 243 | - i = (int)hexc[0]; | ||
| 244 | - if (!isxdigit(i)) | ||
| 245 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 246 | - hexc[1] = (char) toupper((int)obj[2]); | ||
| 247 | - i = (int)hexc[1]; | ||
| 248 | - if (!isxdigit(i)) | ||
| 249 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 250 | - hexc[2] = '\0'; | ||
| 251 | - strncat(l->search_ip, hexc, 2); | ||
| 252 | - break; | ||
| 253 | - case 2: | ||
| 254 | - strncat(l->search_ip, "00", 2); | ||
| 255 | - hexc[0] = (char) toupper((int)obj[0]); | ||
| 256 | - i = (int)hexc[0]; | ||
| 257 | - if (!isxdigit(i)) | ||
| 258 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 259 | - hexc[1] = (char) toupper((int)obj[1]); | ||
| 260 | - i = (int)hexc[1]; | ||
| 261 | - if (!isxdigit(i)) | ||
| 262 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 263 | - hexc[2] = '\0'; | ||
| 264 | - strncat(l->search_ip, hexc, 2); | ||
| 265 | - break; | ||
| 266 | - case 1: | ||
| 267 | - strncat(l->search_ip, "00", 2); | ||
| 268 | - hexc[0] = '0'; | ||
| 269 | - hexc[1] = (char) toupper((int)obj[0]); | ||
| 270 | - i = (int)hexc[1]; | ||
| 271 | - if (!isxdigit(i)) | ||
| 272 | - return LDAP_ERR_OOB; /* Out of bounds */ | ||
| 273 | - hexc[2] = '\0'; | ||
| 274 | - strncat(l->search_ip, hexc, 2); | ||
| 275 | - break; | ||
| 276 | - default: | ||
| 277 | - if (t > 4) | ||
| 278 | - return LDAP_ERR_OOB; | ||
| 279 | - break; | ||
| 280 | - } | ||
| 281 | - /* Code to pad the address with 0's between a '::' */ | ||
| 282 | - if ((strlen(bufa) == 0) && (swi == 1)) { | ||
| 283 | - /* We are *AT* the split, pad in some 0000 */ | ||
| 284 | - t = strlen(bufb); | ||
| 285 | - /* How many ':' exist in bufb ? */ | ||
| 286 | - j = 0; | ||
| 287 | - for (i = 0; i < t; ++i) { | ||
| 288 | - if (bufb[i] == ':') | ||
| 289 | - ++j; | ||
| 290 | - } | ||
| 291 | - --j; /* Preceding "::" doesn't count */ | ||
| 292 | - t = 8 - (strlen(l->search_ip) / 4) - j; /* Remainder */ | ||
| 293 | - if (t > 0) { | ||
| 294 | - for (i = 0; i < t; ++i) | ||
| 295 | - strncat(l->search_ip, "0000", 4); | ||
| 296 | - } | ||
| 297 | - } | ||
| 298 | - } | ||
| 299 | - if ((bufa[0] == '\0') && (swi > 0)) { | ||
| 300 | - s = strlen(bufb); | ||
| 301 | - ++swi; | ||
| 302 | - } else | ||
| 303 | - s = strlen(bufa); | ||
| 304 | - } | ||
| 305 | - s = strlen(l->search_ip); | ||
| 306 | |||
| 307 | - /* CHECK sizes of address, truncate or pad */ | ||
| 308 | - /* if "::" is at end of ip, then pad another block or two */ | ||
| 309 | - while ((l->status & LDAP_IPV6_S) && (s < 32)) { | ||
| 310 | - strncat(l->search_ip, "0000", 4); | ||
| 311 | - s = strlen(l->search_ip); | ||
| 312 | - } | ||
| 313 | - if ((l->status & LDAP_IPV6_S) && (s > 32)) { | ||
| 314 | - /* Too long, truncate */ | ||
| 315 | - l->search_ip[32] = '\0'; | ||
| 316 | - s = strlen(l->search_ip); | ||
| 317 | - } | ||
| 318 | - /* If at end of ip, and its not long enough, then pad another block or two */ | ||
| 319 | - while ((l->status & LDAP_IPV4_S) && (s < 8)) { | ||
| 320 | - strncat(l->search_ip, "00", 2); | ||
| 321 | - s = strlen(l->search_ip); | ||
| 322 | - } | ||
| 323 | - if ((l->status & LDAP_IPV4_S) && (s > 8)) { | ||
| 324 | - /* Too long, truncate */ | ||
| 325 | - l->search_ip[8] = '\0'; | ||
| 326 | - s = strlen(l->search_ip); | ||
| 327 | + size_t s = LDAP_ERR_INVALID; | ||
| 328 | + if (struct addrinfo *dst = makeIpBinary(ip)) { | ||
| 329 | + if (dst->ai_family == AF_INET6) { | ||
| 330 | + struct sockaddr_in6 *sia = reinterpret_cast<struct sockaddr_in6 *>(dst->ai_addr); | ||
| 331 | + const char *ia = reinterpret_cast<const char *>(sia->sin6_addr.s6_addr); | ||
| 332 | + s = makeHexString(l->search_ip, sizeof(l->search_ip), ia, 16); // IPv6 = 16-byte address | ||
| 333 | + | ||
| 334 | + } else if (dst->ai_family == AF_INET) { | ||
| 335 | + struct sockaddr_in *sia = reinterpret_cast<struct sockaddr_in *>(dst->ai_addr); | ||
| 336 | + const char *ia = reinterpret_cast<const char *>(&(sia->sin_addr)); | ||
| 337 | + s = makeHexString(l->search_ip, sizeof(l->search_ip), ia, 4); // IPv4 = 4-byte address | ||
| 338 | + } // else leave s with LDAP_ERR_INVALID value | ||
| 339 | + freeaddrinfo(dst); | ||
| 340 | } | ||
| 341 | |||
| 342 | - /* Completed, s is length of address in HEX */ | ||
| 343 | return s; | ||
| 344 | } | ||
| 345 | |||
| 346 | @@ -1099,48 +993,42 @@ SearchFilterLDAP(edui_ldap_t *l, char *group) | ||
| 347 | } | ||
| 348 | if (group == NULL) { | ||
| 349 | /* No groupMembership= to add, yay! */ | ||
| 350 | - xstrncpy(bufa, "(&", sizeof(bufa)); | ||
| 351 | - strncat(bufa, edui_conf.search_filter, strlen(edui_conf.search_filter)); | ||
| 352 | /* networkAddress */ | ||
| 353 | - snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)", bufc); | ||
| 354 | if (l->status & LDAP_IPV4_S) { | ||
| 355 | - int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s))", \ | ||
| 356 | - bufc, bufc); | ||
| 357 | - strncat(bufb, bufd, ln); | ||
| 358 | + const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", bufc, bufc); | ||
| 359 | + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) | ||
| 360 | + return LDAP_ERR_OOB; | ||
| 361 | + | ||
| 362 | } else if (l->status & LDAP_IPV6_S) { | ||
| 363 | - int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \ | ||
| 364 | - bufc, bufc); | ||
| 365 | - strncat(bufb, bufd, ln); | ||
| 366 | - } else | ||
| 367 | - strncat(bufb, ")", 1); | ||
| 368 | - strncat(bufa, bufb, strlen(bufb)); | ||
| 369 | - strncat(bufa, ")", 1); | ||
| 370 | + const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s)", bufc, bufc); | ||
| 371 | + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) | ||
| 372 | + return LDAP_ERR_OOB; | ||
| 373 | + } | ||
| 374 | + const int x = snprintf(bufa, sizeof(bufa), "(&%s(|(networkAddress=1\\23%s)%s))", edui_conf.search_filter, bufc, bufd); | ||
| 375 | + if (x < 0 || static_cast<size_t>(x) >= sizeof(bufa)) | ||
| 376 | + return LDAP_ERR_OOB; | ||
| 377 | + | ||
| 378 | } else { | ||
| 379 | /* Needs groupMembership= to add... */ | ||
| 380 | - xstrncpy(bufa, "(&(&", sizeof(bufa)); | ||
| 381 | - strncat(bufa, edui_conf.search_filter, strlen(edui_conf.search_filter)); | ||
| 382 | /* groupMembership -- NOTE: Squid *MUST* provide "cn=" from squid.conf */ | ||
| 383 | - snprintf(bufg, sizeof(bufg), "(groupMembership=%s", group); | ||
| 384 | if ((l->basedn[0] != '\0') && (strstr(group, l->basedn) == NULL)) { | ||
| 385 | - strncat(bufg, ",", 1); | ||
| 386 | - strncat(bufg, l->basedn, strlen(l->basedn)); | ||
| 387 | + const int ln = snprintf(bufg, sizeof(bufg), ",%s", l->basedn); | ||
| 388 | + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) | ||
| 389 | + return LDAP_ERR_OOB; | ||
| 390 | } | ||
| 391 | - strncat(bufg, ")", 1); | ||
| 392 | - strncat(bufa, bufg, strlen(bufg)); | ||
| 393 | /* networkAddress */ | ||
| 394 | - snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)", bufc); | ||
| 395 | if (l->status & LDAP_IPV4_S) { | ||
| 396 | - int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s))", \ | ||
| 397 | - bufc, bufc); | ||
| 398 | - strncat(bufb, bufd, ln); | ||
| 399 | + const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", bufc, bufc); | ||
| 400 | + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) | ||
| 401 | + return LDAP_ERR_OOB; | ||
| 402 | } else if (l->status & LDAP_IPV6_S) { | ||
| 403 | - int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \ | ||
| 404 | - bufc, bufc); | ||
| 405 | - strncat(bufb, bufd, ln); | ||
| 406 | - } else | ||
| 407 | - strncat(bufb, ")", 1); | ||
| 408 | - strncat(bufa, bufb, strlen(bufb)); | ||
| 409 | - strncat(bufa, "))", 2); | ||
| 410 | + const int ln = snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s)", bufc, bufc); | ||
| 411 | + if (ln < 0 || static_cast<size_t>(ln) >= sizeof(bufd)) | ||
| 412 | + return LDAP_ERR_OOB; | ||
| 413 | + } | ||
| 414 | + const int x = snprintf(bufa, sizeof(bufa), "(&(&%s(groupMembership=%s%s)(|(networkAddress=1\\23%s)%s)))", edui_conf.search_filter, group, bufg, bufc, bufd); | ||
| 415 | + if (x < 0 || static_cast<size_t>(x) >= sizeof(bufa)) | ||
| 416 | + return LDAP_ERR_OOB; | ||
| 417 | } | ||
| 418 | s = strlen(bufa); | ||
| 419 | xstrncpy(l->search_filter, bufa, sizeof(l->search_filter)); | ||
| 420 | @@ -1212,10 +1100,10 @@ static int | ||
| 421 | SearchIPLDAP(edui_ldap_t *l) | ||
| 422 | { | ||
| 423 | ber_len_t i, x; | ||
| 424 | - ber_len_t j, k; | ||
| 425 | - ber_len_t y, z; | ||
| 426 | - int c; | ||
| 427 | - char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], hexc[4]; | ||
| 428 | + ber_len_t j; | ||
| 429 | + ber_len_t z; | ||
| 430 | + char bufa[EDUI_MAXLEN]; | ||
| 431 | + char bufb[EDUI_MAXLEN]; | ||
| 432 | LDAPMessage *ent; | ||
| 433 | if (l == NULL) return LDAP_ERR_NULL; | ||
| 434 | if (l->lp == NULL) return LDAP_ERR_POINTER; | ||
| 435 | @@ -1273,19 +1161,11 @@ SearchIPLDAP(edui_ldap_t *l) | ||
| 436 | /* bufa is the address, just compare it */ | ||
| 437 | if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) | ||
| 438 | break; /* Not looking for IPv4 */ | ||
| 439 | - for (k = 0; k < z; ++k) { | ||
| 440 | - c = (int) bufa[k]; | ||
| 441 | - if (c < 0) | ||
| 442 | - c = c + 256; | ||
| 443 | - int hlen = snprintf(hexc, sizeof(hexc), "%02X", c); | ||
| 444 | - if (k == 0) | ||
| 445 | - xstrncpy(bufb, hexc, sizeof(bufb)); | ||
| 446 | - else | ||
| 447 | - strncat(bufb, hexc, hlen); | ||
| 448 | - } | ||
| 449 | - y = strlen(bufb); | ||
| 450 | + const int blen = makeHexString(bufb, sizeof(bufb), bufa, z); | ||
| 451 | + if (blen < 0) | ||
| 452 | + return blen; | ||
| 453 | /* Compare value with IP */ | ||
| 454 | - if (memcmp(l->search_ip, bufb, y) == 0) { | ||
| 455 | + if (memcmp(l->search_ip, bufb, blen) == 0) { | ||
| 456 | /* We got a match! - Scan 'ber' for 'cn' values */ | ||
| 457 | z = ldap_count_values_len(ber); | ||
| 458 | for (j = 0; j < z; ++j) { | ||
| 459 | @@ -1308,19 +1188,11 @@ SearchIPLDAP(edui_ldap_t *l) | ||
| 460 | /* bufa + 2 is the address (skip 2 digit port) */ | ||
| 461 | if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) | ||
| 462 | break; /* Not looking for IPv4 */ | ||
| 463 | - for (k = 2; k < z; ++k) { | ||
| 464 | - c = (int) bufa[k]; | ||
| 465 | - if (c < 0) | ||
| 466 | - c = c + 256; | ||
| 467 | - int hlen = snprintf(hexc, sizeof(hexc), "%02X", c); | ||
| 468 | - if (k == 2) | ||
| 469 | - xstrncpy(bufb, hexc, sizeof(bufb)); | ||
| 470 | - else | ||
| 471 | - strncat(bufb, hexc, hlen); | ||
| 472 | - } | ||
| 473 | - y = strlen(bufb); | ||
| 474 | + const int blen = makeHexString(bufb, sizeof(bufb), &bufa[2], z); | ||
| 475 | + if (blen < 0) | ||
| 476 | + return blen; | ||
| 477 | /* Compare value with IP */ | ||
| 478 | - if (memcmp(l->search_ip, bufb, y) == 0) { | ||
| 479 | + if (memcmp(l->search_ip, bufb, blen) == 0) { | ||
| 480 | /* We got a match! - Scan 'ber' for 'cn' values */ | ||
| 481 | z = ldap_count_values_len(ber); | ||
| 482 | for (j = 0; j < z; ++j) { | ||
| 483 | @@ -1343,19 +1215,11 @@ SearchIPLDAP(edui_ldap_t *l) | ||
| 484 | /* bufa + 2 is the address (skip 2 digit port) */ | ||
| 485 | if (!(l->status & LDAP_IPV6_S)) | ||
| 486 | break; /* Not looking for IPv6 */ | ||
| 487 | - for (k = 2; k < z; ++k) { | ||
| 488 | - c = (int) bufa[k]; | ||
| 489 | - if (c < 0) | ||
| 490 | - c = c + 256; | ||
| 491 | - int hlen = snprintf(hexc, sizeof(hexc), "%02X", c); | ||
| 492 | - if (k == 2) | ||
| 493 | - xstrncpy(bufb, hexc, sizeof(bufb)); | ||
| 494 | - else | ||
| 495 | - strncat(bufb, hexc, hlen); | ||
| 496 | - } | ||
| 497 | - y = strlen(bufb); | ||
| 498 | + const int blen = makeHexString(bufb, sizeof(bufb), &bufa[2], z); | ||
| 499 | + if (blen < 0) | ||
| 500 | + return blen; | ||
| 501 | /* Compare value with IP */ | ||
| 502 | - if (memcmp(l->search_ip, bufb, y) == 0) { | ||
| 503 | + if (memcmp(l->search_ip, bufb, blen) == 0) { | ||
| 504 | /* We got a match! - Scan 'ber' for 'cn' values */ | ||
| 505 | z = ldap_count_values_len(ber); | ||
| 506 | for (j = 0; j < z; ++j) { | ||
diff --git a/meta-networking/recipes-daemons/squid/files/0002-smblib-fix-buffer-over-read.patch b/meta-networking/recipes-daemons/squid/files/0002-smblib-fix-buffer-over-read.patch new file mode 100644 index 0000000000..c8f0c47bd1 --- /dev/null +++ b/meta-networking/recipes-daemons/squid/files/0002-smblib-fix-buffer-over-read.patch | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | From a6b1e0fd14311587186e40d09bff5c8c3aada2e4 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Amos Jeffries <squid3@treenet.co.nz> | ||
| 3 | Date: Sat, 25 Jul 2015 05:53:16 -0700 | ||
| 4 | Subject: [PATCH] smblib: fix buffer over-read | ||
| 5 | |||
| 6 | When parsing SMB LanManager packets with invalid protocol ID and the | ||
| 7 | default set of Squid supported protocols. It may access memory outside | ||
| 8 | the buffer storing protocol names. | ||
| 9 | |||
| 10 | smblib is only used by already deprecated helpers which are deprecated | ||
| 11 | due to far more significant NTLM protocol issues. It will also only | ||
| 12 | result in packets being rejected later with invalid protocol names. So | ||
| 13 | this is a minor bug rather than a vulnerability. | ||
| 14 | |||
| 15 | Detected by Coverity Scan. Issue 1256165 | ||
| 16 | --- | ||
| 17 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
| 18 | Upstream-Status: Backport | ||
| 19 | |||
| 20 | lib/smblib/smblib-util.c | 6 +++++- | ||
| 21 | 1 file changed, 5 insertions(+), 1 deletion(-) | ||
| 22 | |||
| 23 | diff --git a/lib/smblib/smblib-util.c b/lib/smblib/smblib-util.c | ||
| 24 | index 6139ae2..e722cbb 100644 | ||
| 25 | --- a/lib/smblib/smblib-util.c | ||
| 26 | +++ b/lib/smblib/smblib-util.c | ||
| 27 | @@ -204,7 +204,11 @@ int SMB_Figure_Protocol(const char *dialects[], int prot_index) | ||
| 28 | { | ||
| 29 | int i; | ||
| 30 | |||
| 31 | - if (dialects == SMB_Prots) { /* The jobs is easy, just index into table */ | ||
| 32 | + // prot_index may be a value outside the table SMB_Types[] | ||
| 33 | + // which holds data at offsets 0 to 11 | ||
| 34 | + int ourType = (prot_index < 0 || prot_index > 11); | ||
| 35 | + | ||
| 36 | + if (ourType && dialects == SMB_Prots) { /* The jobs is easy, just index into table */ | ||
| 37 | |||
| 38 | return(SMB_Types[prot_index]); | ||
| 39 | } else { /* Search through SMB_Prots looking for a match */ | ||
diff --git a/meta-networking/recipes-daemons/squid/squid_3.5.27.bb b/meta-networking/recipes-daemons/squid/squid_3.5.27.bb index 7dae3cd83f..1557c4b2d6 100644 --- a/meta-networking/recipes-daemons/squid/squid_3.5.27.bb +++ b/meta-networking/recipes-daemons/squid/squid_3.5.27.bb | |||
| @@ -23,6 +23,8 @@ SRC_URI = "http://www.squid-cache.org/Versions/v${MAJ_VER}/${MIN_VER}/${BPN}-${P | |||
| 23 | file://squid-don-t-do-squid-conf-tests-at-build-time.patch \ | 23 | file://squid-don-t-do-squid-conf-tests-at-build-time.patch \ |
| 24 | file://0001-configure-Check-for-Wno-error-format-truncation-comp.patch \ | 24 | file://0001-configure-Check-for-Wno-error-format-truncation-comp.patch \ |
| 25 | file://0001-tools.cc-fixed-unused-result-warning.patch \ | 25 | file://0001-tools.cc-fixed-unused-result-warning.patch \ |
| 26 | file://0001-Bug-4843-pt1-ext_edirectory_userip_acl-refactoring-f.patch \ | ||
| 27 | file://0002-smblib-fix-buffer-over-read.patch \ | ||
| 26 | " | 28 | " |
| 27 | 29 | ||
| 28 | SRC_URI_remove_toolchain-clang = "file://0001-configure-Check-for-Wno-error-format-truncation-comp.patch" | 30 | 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', ' | |||
| 48 | PACKAGECONFIG[libnetfilter-conntrack] = "--with-netfilter-conntrack=${includedir}, --without-netfilter-conntrack, libnetfilter-conntrack" | 50 | PACKAGECONFIG[libnetfilter-conntrack] = "--with-netfilter-conntrack=${includedir}, --without-netfilter-conntrack, libnetfilter-conntrack" |
| 49 | PACKAGECONFIG[noatomics] = "squid_cv_gnu_atomics=no,squid_cv_gnu_atomics=yes,," | 51 | PACKAGECONFIG[noatomics] = "squid_cv_gnu_atomics=no,squid_cv_gnu_atomics=yes,," |
| 50 | PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6," | 52 | PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6," |
| 53 | PACKAGECONFIG[werror] = "--enable-strict-error-checking,--disable-strict-error-checking," | ||
| 51 | 54 | ||
| 52 | BASIC_AUTH = "DB SASL LDAP" | 55 | BASIC_AUTH = "DB SASL LDAP" |
| 53 | 56 | ||
