mirror of
https://github.com/haproxy/haproxy.git
synced 2026-05-28 04:12:17 -04:00
BUG/MEDIUM: net_helper: fix a remaining possibly infinite loop in converters
The various tcp_option_* converters rely on tcp_fullhdr_find_opt() to
find the option. However, the same bug as fixed in commit dbf471f99a
("BUG/MAJOR: net_helper: ip.fp infinite loop on malformed tcp options")
was also present there, by which an option of length 0 could be looped
over indefinitely. In practice this does not happen since such options
are not valid, but if passed encoded in an HTTP header for example, it
could possibly be passed.
While fixing it, let's check for length >1 in all 3 locations insteead
of only non-zero, since there's no point processing a malformed option
that wouldn't even be properly skipped.
This fix doesn't need to be backported, unless the ip.fp series is.
Thanks to @Vincent55 for reporting this issue.
This commit is contained in:
parent
3475a5bb9f
commit
413f6f9a1f
1 changed files with 4 additions and 4 deletions
|
|
@ -447,8 +447,8 @@ static size_t tcp_fullhdr_find_opt(const struct sample *smp, uint8_t opt)
|
|||
/* kind1 = NOP and is a single byte, others have a length field */
|
||||
if (smp->data.u.str.area[next] == 1)
|
||||
next++;
|
||||
else if (next + 1 < len)
|
||||
next += smp->data.u.str.area[next + 1];
|
||||
else if (next + 1 < len && smp->data.u.str.area[next + 1] > 1)
|
||||
next += (uchar)smp->data.u.str.area[next + 1];
|
||||
else
|
||||
break;
|
||||
if (smp->data.u.str.area[curr] == opt && next <= len)
|
||||
|
|
@ -605,7 +605,7 @@ static int sample_conv_tcp_options_list(const struct arg *arg_p, struct sample *
|
|||
/* kind1 = NOP and is a single byte, others have a length field */
|
||||
if (smp->data.u.str.area[ofs] == 1)
|
||||
ofs++;
|
||||
else if (ofs + 1 < len && smp->data.u.str.area[ofs + 1])
|
||||
else if (ofs + 1 < len && smp->data.u.str.area[ofs + 1] > 1)
|
||||
ofs += (uchar)smp->data.u.str.area[ofs + 1];
|
||||
else
|
||||
break;
|
||||
|
|
@ -780,7 +780,7 @@ static int sample_conv_ip_fp(const struct arg *arg_p, struct sample *smp, void *
|
|||
/* kind1 = NOP and is a single byte, others have a length field */
|
||||
if (smp->data.u.str.area[ofs] == 1)
|
||||
next = ofs + 1;
|
||||
else if ((ofs + 1 < tcplen) && smp->data.u.str.area[ofs + 1]) /* optlen 0 will cause an infinite loop */
|
||||
else if ((ofs + 1 < tcplen) && smp->data.u.str.area[ofs + 1] > 1)
|
||||
next = ofs + (uchar)smp->data.u.str.area[ofs + 1];
|
||||
else
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in a new issue