tags -1 + patch,pending user debian-rele...@lists.debian.org usertags -1 + bsp-2021-03-latinoamerica thank you
Hi, I have prepared this patch and will be performing an upload targetted at delayed/7-day. Dmitry, please do take a look at my proposed patch. I backported the commit I'm quoting in it, which applied quite imperfectly; I am basically sure the code I applied is correct (but extra eyes will never hurt!), but I left out the patch for backend/tests/test_upcean.c, as the version we are shipping is very much behind (the patched functions don't even exist). Greetings,
Last-Update: 2021-03-11 Origin: https://sourceforge.net/p/zint/code/ci/7f8c8114f31c09a986597e0ba63a49f96150368a/ Forwarded: not-needed Author: Gunnar Wolf <gw...@debian.org> Description: Fix a buffer overflow in ean_laeding_zeroes This vulnerability is tracked as CVE-2021-27799. The patch was backported from the devel git tree. Index: zint-2.9.1/backend/composite.c =================================================================== --- zint-2.9.1.orig/backend/composite.c +++ zint-2.9.1/backend/composite.c @@ -65,7 +65,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); -INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]); +INTERNAL int ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]); INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); @@ -1422,7 +1422,10 @@ INTERNAL int composite(struct zint_symbo int padded_pri_len; char padded_pri[20]; padded_pri[0] = '\0'; - ean_leading_zeroes(symbol, (unsigned char *) symbol->primary, (unsigned char *) padded_pri); + if (!ean_leading_zeroes(symbol, (unsigned char *) symbol->primary, (unsigned char *) padded_pri)) { + strcpy(symbol->errtxt, "448: Input wrong length in linear component"); + return ZINT_ERROR_TOO_LONG; + } padded_pri_len = strlen(padded_pri); if (padded_pri_len <= 7) { /* EAN-8 */ cc_width = 3; Index: zint-2.9.1/backend/upcean.c =================================================================== --- zint-2.9.1.orig/backend/upcean.c +++ zint-2.9.1/backend/upcean.c @@ -125,7 +125,7 @@ static void upca_draw(char source[], cha /* Make a UPC A barcode when we haven't been given the check digit */ static int upca(struct zint_symbol *symbol, unsigned char source[], char dest[]) { int length; - char gtin[15]; + char gtin[13]; strcpy(gtin, (char*) source); length = strlen(gtin); @@ -391,7 +391,7 @@ static char ean_check(char source[]) { static int ean13(struct zint_symbol *symbol, unsigned char source[], char dest[]) { unsigned int length, i, half_way; char parity[6]; - char gtin[15]; + char gtin[14]; strcpy(parity, ""); strcpy(gtin, (char*) source); @@ -569,8 +569,9 @@ static int isbn(struct zint_symbol *symb } /* Add leading zeroes to EAN and UPC strings */ -INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]) { - unsigned char first_part[20], second_part[20], zfirst_part[20], zsecond_part[20]; +INTERNAL int ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], + unsigned char local_source[], int *p_with_addon) { + unsigned char first_part[14], second_part[6], zfirst_part[14], zsecond_part[6]; int with_addon = 0; int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h; @@ -592,15 +593,16 @@ INTERNAL void ean_leading_zeroes(struct ustrcpy(zfirst_part, (unsigned char *) ""); ustrcpy(zsecond_part, (unsigned char *) ""); + if (first_len > 13 || second_len > 5) { + return 0; + } + /* Split input into two strings */ for (i = 0; i < first_len; i++) { first_part[i] = source[i]; first_part[i + 1] = '\0'; } - if (second_len >= 6) { /* Allow 6 (actual max 5) so as to trigger too long error */ - second_len = 6; - } for (i = 0; i < second_len; i++) { second_part[i] = source[i + first_len + 1]; second_part[i + 1] = '\0'; @@ -698,12 +700,13 @@ INTERNAL void ean_leading_zeroes(struct strcat((char*) local_source, "+"); strcat((char*) local_source, (char*) zsecond_part); } + + return 1; /* Success */ } -/* splits string to parts before and after '+' parts */ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) { - unsigned char first_part[20] = {0}, second_part[7] = {0}, dest[1000] = {0}; - unsigned char local_source[20] = {0}; + unsigned char first_part[14] = {0}, second_part[6] = {0}, dest[1000] = {0}; + unsigned char local_source[20] = {0}; /* Allow 13 + "+" + 5 + 1 */ unsigned int latch, reader, writer, with_addon; int error_number, i, plus_count; int addon_gap = 0; @@ -743,8 +746,11 @@ INTERNAL int eanx(struct zint_symbol *sy return ZINT_ERROR_INVALID_DATA; } - /* Add leading zeroes */ - ean_leading_zeroes(symbol, source, local_source); + /* Add leading zeroes, checking max lengths of parts */ + if (!ean_leading_zeroes(symbol, source, local_source, &with_addon)) { + strcpy(symbol->errtxt, "294: Input too long"); + return ZINT_ERROR_TOO_LONG; + } for (reader = 0; reader < ustrlen(local_source); reader++) { if (local_source[reader] == '+') {
signature.asc
Description: PGP signature