From 5fd72284149ff170f223f423cf58149f49efd864 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sun, 24 Mar 2019 15:44:33 +0100 Subject: [PATCH] intmatcher: Catch out of bounds reads Credit to OSS-Fuzz which reported this issue: intmatcher.cpp:1163:17: runtime error: index 24 out of bounds for type 'uint8_t [24]' #0 0x610d3b in ScratchEvidence::UpdateSumOfProtoEvidences(INT_CLASS_STRUCT*, unsigned int*) tesseract/src/classify/intmatcher.cpp:1163:17 #1 0x60ff4e in IntegerMatcher::Match(INT_CLASS_STRUCT*, unsigned int*, unsigned int*, short, INT_FEATURE_STRUCT const*, tesseract::UnicharRating*, int, int, bool) tesseract/src/classify/intmatcher.cpp:563:11 #2 0x5f4355 in tesseract::Classify::AdaptToChar(TBLOB*, int, int, float, ADAPT_TEMPLATES_STRUCT*) tesseract/src/classify/adaptmatch.cpp:894:9 #3 0x5f35fd in tesseract::Classify::LearnPieces(char const*, int, int, float, tesseract::CharSegmentationType, char const*, WERD_RES*) tesseract/src/classify/adaptmatch.cpp:430:5 #4 0x5f201e in tesseract::Classify::LearnWord(char const*, WERD_RES*) tesseract/src/classify/adaptmatch.cpp:293:7 This catches the out of bounds data reads, but does not fix the primary reason: ProtoLengths currently gets values which are larger than the allowed index. Signed-off-by: Stefan Weil --- src/classify/intmatcher.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/classify/intmatcher.cpp b/src/classify/intmatcher.cpp index 8e83e46ce6..4f93d39d61 100644 --- a/src/classify/intmatcher.cpp +++ b/src/classify/intmatcher.cpp @@ -621,7 +621,8 @@ int IntegerMatcher::FindGoodProtos( for (int proto = 0; proto < ClassTemplate->NumProtos; proto++) { /* Compute Average for Actual Proto */ int Temp = 0; - for (uint8_t i = 0; i < ClassTemplate->ProtoLengths[proto]; i++) + for (uint8_t i = 0; + i < MAX_PROTO_INDEX && i < ClassTemplate->ProtoLengths[proto]; i++) Temp += tables->proto_evidence_[proto][i]; Temp /= ClassTemplate->ProtoLengths[proto]; @@ -1153,7 +1154,8 @@ void ScratchEvidence::UpdateSumOfProtoEvidences( ((ProtoNum < PROTOS_PER_PROTO_SET) && (ActualProtoNum < NumProtos)); ProtoNum++, ActualProtoNum++) { int temp = 0; - for (uint8_t i = 0; i < ClassTemplate->ProtoLengths[ActualProtoNum]; i++) + for (uint8_t i = 0; i < MAX_PROTO_INDEX && + i < ClassTemplate->ProtoLengths[ActualProtoNum]; i++) temp += proto_evidence_[ActualProtoNum] [i]; ConfigWord = ProtoSet->Protos[ProtoNum].Configs[0];