mirror of
https://github.com/haproxy/haproxy.git
synced 2026-05-28 04:12:17 -04:00
BUG/MINOR: tcpcheck: Check LDAP response to not read more data than available
tcpcheck_ldap_expect_bindrsp() parses ASN.1 BER-encoded LDAP responses from the health check target. After reading the outer message size and validating protocol fields, it encounters a long-form BER length for the bindResponse value (high bit set in the length byte). The code reads nbytes = (*ptr & 0x7f) then advances ptr by 1 + nbytes without checking that enough bytes remain in the receive buffer. So, it is possible to read more data than available. Note that it is only possible if the LDAP response was forged because the message length was already checked. LDAP response remains quite short and it is not possible to read outside the buffer area. So at worst, garbage are parsed and a wrong result is reported by the LDAP health-check. Most probably an error will be reported. This patch could be backported to all stable versions.
This commit is contained in:
parent
88da61e218
commit
31cd3d13aa
1 changed files with 13 additions and 4 deletions
|
|
@ -664,7 +664,7 @@ enum tcpcheck_eval_ret tcpcheck_ldap_expect_bindrsp(struct check *check, struct
|
|||
enum healthcheck_status status;
|
||||
struct buffer *msg = NULL;
|
||||
struct ist desc = IST_NULL;
|
||||
char *ptr;
|
||||
char *ptr, *end;
|
||||
unsigned short nbytes = 0;
|
||||
size_t msglen = 0;
|
||||
|
||||
|
|
@ -674,7 +674,12 @@ enum tcpcheck_eval_ret tcpcheck_ldap_expect_bindrsp(struct check *check, struct
|
|||
* http://en.wikipedia.org/wiki/Basic_Encoding_Rules
|
||||
* http://tools.ietf.org/html/rfc4511
|
||||
*/
|
||||
ptr = b_head(&check->bi) + 1;
|
||||
ptr = b_head(&check->bi);
|
||||
end = ptr + b_data(&check->bi);
|
||||
ptr++; /* First byte was already matched by the previous expect rule
|
||||
* and at least 14 bytes are available
|
||||
* (see do_parse_ldap_check_opt)
|
||||
*/
|
||||
|
||||
/* size of LDAPMessage */
|
||||
if (*ptr & 0x80) {
|
||||
|
|
@ -684,7 +689,7 @@ enum tcpcheck_eval_ret tcpcheck_ldap_expect_bindrsp(struct check *check, struct
|
|||
* encode BindReponse length on 4 bytes.
|
||||
*/
|
||||
nbytes = (*ptr & 0x7f);
|
||||
if (b_data(&check->bi) < 1 + nbytes)
|
||||
if (end - ptr < 1 + nbytes)
|
||||
goto too_short;
|
||||
switch (nbytes) {
|
||||
case 4: msglen = read_n32(ptr+1); break;
|
||||
|
|
@ -699,7 +704,7 @@ enum tcpcheck_eval_ret tcpcheck_ldap_expect_bindrsp(struct check *check, struct
|
|||
msglen = *ptr;
|
||||
ptr += 1 + nbytes;
|
||||
|
||||
if (b_data(&check->bi) < 2 + nbytes + msglen)
|
||||
if (end - ptr < msglen)
|
||||
goto too_short;
|
||||
|
||||
/* http://tools.ietf.org/html/rfc4511#section-4.2.2
|
||||
|
|
@ -717,6 +722,10 @@ enum tcpcheck_eval_ret tcpcheck_ldap_expect_bindrsp(struct check *check, struct
|
|||
nbytes = 0;
|
||||
if (*ptr & 0x80)
|
||||
nbytes = (*ptr & 0x7f);
|
||||
|
||||
if (end - ptr < 1 + nbytes + 2 + 1)
|
||||
goto too_short;
|
||||
|
||||
ptr += 1 + nbytes;
|
||||
|
||||
/* http://tools.ietf.org/html/rfc4511#section-4.1.9
|
||||
|
|
|
|||
Loading…
Reference in a new issue