mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
Fix integer-overflow in ev_token_bucket_cfg_new
Found by oss-fuzz, after coverage had been improved in https://github.com/google/oss-fuzz/pull/11257 v2: better check (found by CI for windows)
This commit is contained in:
parent
c4fb0f7603
commit
e4b8732701
@ -154,7 +154,17 @@ ev_token_bucket_cfg_new(size_t read_rate, size_t read_burst,
|
|||||||
tick_len = &g;
|
tick_len = &g;
|
||||||
}
|
}
|
||||||
|
|
||||||
msec_per_tick = (tick_len->tv_sec * 1000) +
|
/* Avoid possible overflow.
|
||||||
|
* - there is no point in accepting values larger then INT_MAX/1000 anyway
|
||||||
|
* - on windows tv_sec (tv_usec) is long, which is int, which has upper value limit INT_MAX
|
||||||
|
* - and also negative values does not make any sense
|
||||||
|
*/
|
||||||
|
if (tick_len->tv_sec < 0 || tick_len->tv_sec > INT_MAX/1000)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Note, overflow with tv_usec is not possible since tv_sec is limited to
|
||||||
|
* INT_MAX/1000 anyway */
|
||||||
|
msec_per_tick = (unsigned)(tick_len->tv_sec * 1000) +
|
||||||
(tick_len->tv_usec & COMMON_TIMEOUT_MICROSECONDS_MASK)/1000;
|
(tick_len->tv_usec & COMMON_TIMEOUT_MICROSECONDS_MASK)/1000;
|
||||||
if (!msec_per_tick)
|
if (!msec_per_tick)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#ifdef EVENT__HAVE_ARPA_INET_H
|
#ifdef EVENT__HAVE_ARPA_INET_H
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -203,13 +204,52 @@ static void test_bufferevent_pair_flush_normal(void) { test_bufferevent_impl(1,
|
|||||||
static void test_bufferevent_pair_flush_flush(void) { test_bufferevent_impl(1, BEV_FLUSH); }
|
static void test_bufferevent_pair_flush_flush(void) { test_bufferevent_impl(1, BEV_FLUSH); }
|
||||||
static void test_bufferevent_pair_flush_finished(void) { test_bufferevent_impl(1, BEV_FINISHED); }
|
static void test_bufferevent_pair_flush_finished(void) { test_bufferevent_impl(1, BEV_FINISHED); }
|
||||||
|
|
||||||
static void test_bufferevent_ratelimit_fuzz(void)
|
static void test_bufferevent_ratelimit_div_by_zero(void)
|
||||||
{
|
{
|
||||||
struct timeval cfg_tick = {0, 0};
|
struct timeval cfg_tick = {0, 0};
|
||||||
struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new(1, 1, 1, 1, &cfg_tick);
|
struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new(1, 1, 1, 1, &cfg_tick);
|
||||||
tt_ptr_op(cfg, ==, NULL);
|
tt_ptr_op(cfg, ==, NULL);
|
||||||
test_ok = 1;
|
test_ok = 1;
|
||||||
|
|
||||||
|
end:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
static void test_bufferevent_ratelimit_overflow(void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
struct timeval cfg_tick = {LONG_MAX, 0};
|
||||||
|
struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new(1, 1, 1, 1, &cfg_tick);
|
||||||
|
tt_ptr_op(cfg, ==, NULL);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct timeval cfg_tick = {UINT_MAX-1, 0};
|
||||||
|
struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new(1, 1, 1, 1, &cfg_tick);
|
||||||
|
tt_ptr_op(cfg, ==, NULL);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct timeval cfg_tick = {INT_MAX, 0};
|
||||||
|
struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new(1, 1, 1, 1, &cfg_tick);
|
||||||
|
tt_ptr_op(cfg, ==, NULL);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct timeval cfg_tick = {INT_MAX/1000+1, 0};
|
||||||
|
struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new(1, 1, 1, 1, &cfg_tick);
|
||||||
|
tt_ptr_op(cfg, ==, NULL);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct timeval cfg_tick = {INT_MAX/1000, 0};
|
||||||
|
struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new(1, 1, 1, 1, &cfg_tick);
|
||||||
|
tt_ptr_op(cfg, !=, NULL);
|
||||||
|
ev_token_bucket_cfg_free(cfg);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct timeval cfg_tick = {INT_MAX/1000-1, 0};
|
||||||
|
struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new(1, 1, 1, 1, &cfg_tick);
|
||||||
|
tt_ptr_op(cfg, !=, NULL);
|
||||||
|
ev_token_bucket_cfg_free(cfg);
|
||||||
|
}
|
||||||
|
test_ok = 1;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -1474,7 +1514,8 @@ struct testcase_t bufferevent_testcases[] = {
|
|||||||
test_bufferevent_read_failed,
|
test_bufferevent_read_failed,
|
||||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE, &basic_setup, NULL },
|
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE, &basic_setup, NULL },
|
||||||
|
|
||||||
LEGACY(bufferevent_ratelimit_fuzz, TT_ISOLATED),
|
LEGACY(bufferevent_ratelimit_div_by_zero, TT_ISOLATED),
|
||||||
|
LEGACY(bufferevent_ratelimit_overflow, TT_ISOLATED),
|
||||||
|
|
||||||
END_OF_TESTCASES,
|
END_OF_TESTCASES,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user