From f5149990eb7581b9deac47ce83948017882d3e5c Mon Sep 17 00:00:00 2001 From: gitlost Date: Tue, 31 Mar 2020 13:02:53 +0100 Subject: [PATCH] #181 OSS-Fuzz DOTCODE codeword_array buffer overrun fix --- backend/dotcode.c | 8 ++++---- backend/tests/test_dotcode.c | 7 ++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/backend/dotcode.c b/backend/dotcode.c index d589a188..da16ced5 100644 --- a/backend/dotcode.c +++ b/backend/dotcode.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2017-2019 Robin Stuart + Copyright (C) 2017-2020 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -38,7 +38,6 @@ #include #include -#include #include #ifndef _MSC_VER #include @@ -1297,16 +1296,17 @@ INTERNAL int dotcode(struct zint_symbol *symbol, const unsigned char source[], i int binary_finish = 0; int debug = symbol->debug; int padding_dots, is_first; + int codeword_array_len = length * 4 + 8; /* Allow up to 4 codewords per input + 2 (FNC) + 4 (ECI) + 2 (special char 1st position) */ #ifdef _MSC_VER unsigned char* masked_codeword_array; #endif #ifndef _MSC_VER - unsigned char codeword_array[length * 3]; + unsigned char codeword_array[codeword_array_len]; #else char* dot_stream; char* dot_array; - unsigned char* codeword_array = (unsigned char *) _alloca(length * 3 * sizeof (unsigned char)); + unsigned char* codeword_array = (unsigned char *) _alloca(codeword_array_len); #endif /* _MSC_VER */ if (symbol->eci > 811799) { diff --git a/backend/tests/test_dotcode.c b/backend/tests/test_dotcode.c index 7d3cceba..86d84f7e 100644 --- a/backend/tests/test_dotcode.c +++ b/backend/tests/test_dotcode.c @@ -45,7 +45,7 @@ static void test_fuzz(void) }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { "(\207'", -1, DATA_MODE, 0 }, // 0x28,0x87,0x27 Note: should but doesn't trigger sanitize error if no length check, for some reason; TODO: determine why + /* 0*/ { "(\207'", -1, DATA_MODE, 0 }, // 0x28,0x87,0x27 Note: should but doesn't trigger sanitize error if no length check, for some reason; UPDATE: use up-to-date gcc (9)! /* 1*/ { "\133\061\106\133\061\106\070\161\116\133\116\116\067\040\116\016\000\116\125\111\125\125\316\125\125\116\116\116\116\117\116\125" "\111\125\103\316\125\125\116\116\116\116\117\000\000\116\136\116\116\001\116\316\076\116\116\057\136\116\116\134\000\000\116\116" @@ -62,6 +62,11 @@ static void test_fuzz(void) "\071\071\071\011\071\071\071\071\071\071\071\071\071\071\071\071\071\071\105\105\105\105\105\105\105\105\105\105\105\105\105\071" "\071\071\071\071\071", // Original OSS-Fuzz triggering data for index out of bounds (encoding of HT/FS/GS/RS when shifting to code set B) 421, UNICODE_MODE, ZINT_WARN_USES_ECI }, + /* 2*/ { "\233:", -1, UNICODE_MODE, ZINT_WARN_USES_ECI }, // Original OSS-Fuzz triggering data for codeword_array buffer overflow, L777 + /* 3*/ { "\241\034", -1, UNICODE_MODE, ZINT_WARN_USES_ECI }, // As above L793 + /* 4*/ { "\270\036", -1, UNICODE_MODE, ZINT_WARN_USES_ECI }, // As above L799 + /* 5*/ { "\237\032", -1, UNICODE_MODE, ZINT_WARN_USES_ECI }, // As above L904 + /* 6*/ { "\237", -1, UNICODE_MODE, ZINT_WARN_USES_ECI }, // As above L1090 }; int data_size = sizeof(data) / sizeof(struct item);