mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-20 12:46:56 +00:00
BUG/MAJOR: quic: Wrong quic_max_available_room() returned value
Around limits for QUIC integer encoding, this functions could return wrong values which lead to qc_build_frms() to prepare wrong CRYPTO (less chances) or STREAM frames (more chances). qc_do_build_pkt() could build wrong packets with bad CRYPTO/STREAM frames which could not be decoded by the peer. In such a case ngtcp2 closes the connection with an ENCRYPTION_ERROR error in a transport CONNECTION_CLOSE frame.
This commit is contained in:
parent
4fe7d8a5b2
commit
5bcfd33063
@ -331,7 +331,8 @@ static inline uint64_t quic_max_int(size_t sz)
|
||||
* buffer with <sz> as size for a data field of bytes prefixed by its QUIC
|
||||
* variable-length (may be 0).
|
||||
* Also put in <*len_sz> the size of this QUIC variable-length.
|
||||
* So after returning from this function we have : <*len_sz> + <ret> = <sz>.
|
||||
* So after returning from this function we have : <*len_sz> + <ret> <= <sz>
|
||||
* (<*len_sz> = { max(i), i + ret <= <sz> }) .
|
||||
*/
|
||||
static inline size_t max_available_room(size_t sz, size_t *len_sz)
|
||||
{
|
||||
@ -346,8 +347,22 @@ static inline size_t max_available_room(size_t sz, size_t *len_sz)
|
||||
*len_sz = quic_int_getsize(ret);
|
||||
/* Difference between the two sizes. Note that <sz_sz> >= <*len_sz>. */
|
||||
diff = sz_sz - *len_sz;
|
||||
if (unlikely(diff > 0))
|
||||
ret += diff;
|
||||
if (unlikely(diff > 0)) {
|
||||
/* Let's try to take into an account remaining bytes.
|
||||
*
|
||||
* <----------------> <sz_sz>
|
||||
* <--------------><--------> +----> <max_int>
|
||||
* <ret> <len_sz> |
|
||||
* +---------------------------+-----------....
|
||||
* <--------------------------------> <sz>
|
||||
*/
|
||||
size_t max_int = quic_max_int_by_size(*len_sz);
|
||||
|
||||
if (max_int + *len_sz <= sz)
|
||||
ret = max_int;
|
||||
else
|
||||
ret = sz - diff;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user