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] == '+') {

Attachment: signature.asc
Description: PGP signature

Reply via email to