[kerx] Fix integer overflow in multiply

Fixes https://oss-fuzz.com/v2/testcase-detail/5754863779053568
This commit is contained in:
Behdad Esfahbod 2018-11-12 14:11:29 -05:00
parent 1300f027a9
commit c8f4cc4927
2 changed files with 17 additions and 14 deletions

View File

@ -267,7 +267,7 @@ struct KerxSubTableFormat1
unsigned int kern_idx = Format1EntryT::kernActionIndex (entry); unsigned int kern_idx = Format1EntryT::kernActionIndex (entry);
kern_idx = Types::offsetToIndex (kern_idx, &table->machine, kernAction.arrayZ); kern_idx = Types::offsetToIndex (kern_idx, &table->machine, kernAction.arrayZ);
const FWORD *actions = &kernAction[kern_idx]; const FWORD *actions = &kernAction[kern_idx];
if (!c->sanitizer.check_array (actions, depth * tuple_count)) if (!c->sanitizer.check_array2 (actions, depth, tuple_count))
{ {
depth = 0; depth = 0;
return false; return false;

View File

@ -298,7 +298,8 @@ struct hb_sanitize_context_t :
this->start = this->end = nullptr; this->start = this->end = nullptr;
} }
inline bool check_range (const void *base, unsigned int len) const inline bool check_range (const void *base,
unsigned int len) const
{ {
const char *p = (const char *) base; const char *p = (const char *) base;
bool ok = this->start <= p && bool ok = this->start <= p &&
@ -316,20 +317,22 @@ struct hb_sanitize_context_t :
} }
template <typename T> template <typename T>
inline bool check_array (const T *base, unsigned int len, unsigned int record_size = T::static_size) const inline bool check_array (const T *base,
unsigned int len,
unsigned int record_size = T::static_size) const
{ {
const char *p = (const char *) base; return !hb_unsigned_mul_overflows (len, record_size) &&
bool overflows = hb_unsigned_mul_overflows (len, record_size); this->check_range (base, len * record_size);
unsigned int array_size = record_size * len; }
bool ok = !overflows && this->check_range (base, array_size);
DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, template <typename T>
"check_array [%p..%p] (%d*%d=%d bytes) in [%p..%p] -> %s", inline bool check_array2 (const T *base,
p, p + (record_size * len), record_size, len, (unsigned int) array_size, unsigned int a,
this->start, this->end, unsigned int b,
overflows ? "OVERFLOWS" : ok ? "OK" : "OUT-OF-RANGE"); unsigned int record_size = T::static_size) const
{
return likely (ok); return !hb_unsigned_mul_overflows (a, b) &&
this->check_array (base, a * b, record_size);
} }
template <typename Type> template <typename Type>