Hi all, Moritz - did you take a look at my patch? I'd really like to have a second opinion on that since it is fairly large for an NMU.
I attach NMU patch. Shall I upload it to DELAYED/5 or something like that? Cheers, Tomasz
diff -Nru potrace-1.11/debian/changelog potrace-1.11/debian/changelog --- potrace-1.11/debian/changelog 2015-03-17 08:16:28.000000000 +0100 +++ potrace-1.11/debian/changelog 2015-03-17 08:19:09.000000000 +0100 @@ -1,3 +1,10 @@ +potrace (1.11-2.1) testing; urgency=medium + + * Non-maintainer upload. + * Fix multiple integer overflows (Closes: #778646) + + -- Tomasz Buchert <tom...@debian.org> Tue, 17 Mar 2015 08:11:24 +0100 + potrace (1.11-2) unstable; urgency=low * Uses dh-autoreconf instead of autotools-dev (Closes: #732923) diff -Nru potrace-1.11/debian/patches/0002-Fix-multiple-integer-overflows.patch potrace-1.11/debian/patches/0002-Fix-multiple-integer-overflows.patch --- potrace-1.11/debian/patches/0002-Fix-multiple-integer-overflows.patch 1970-01-01 01:00:00.000000000 +0100 +++ potrace-1.11/debian/patches/0002-Fix-multiple-integer-overflows.patch 2015-03-17 08:19:09.000000000 +0100 @@ -0,0 +1,172 @@ +From: Tomasz Buchert <tom...@debian.org> +Date: Sun, 1 Mar 2015 20:27:29 +0100 +Subject: Fix multiple integer overflows. + +Dimensions of a BMP file are signed, 4-byte integers. Therefore the size +of the image may be bigger than range of (int). This is fixed in +bitmap.h, by casting all offsets to unsigned long long int (and fixing +another possible overflow in bm_new). + +In bitmap_io.c we make sure that width and height of the image are +non-negative and in (int) range, because other functions require it. + +Moreover, we make sure that allocations do not overflow the range of +size_t by having a wrapper (safe_malloc) that tests whether the +allocation size fits in size_t. +--- + src/bitmap.h | 35 +++++++++++++++++++++++++++-------- + src/bitmap_io.c | 30 +++++++++++++++++++++++++++--- + 2 files changed, 54 insertions(+), 11 deletions(-) + +diff --git a/src/bitmap.h b/src/bitmap.h +index 1ce13d6..7110926 100644 +--- a/src/bitmap.h ++++ b/src/bitmap.h +@@ -7,6 +7,7 @@ + + #include <string.h> + #include <stdlib.h> ++#include <errno.h> + + /* The bitmap type is defined in potracelib.h */ + #include "potracelib.h" +@@ -27,7 +28,10 @@ + /* macros for accessing pixel at index (x,y). U* macros omit the + bounds check. */ + +-#define bm_scanline(bm, y) ((bm)->map + (y)*(bm)->dy) ++typedef unsigned long long int ulli; ++ ++#define bm_allocsize(bm) ((ulli)(bm)->dy * (ulli)(bm)->h) ++#define bm_scanline(bm, y) ((bm)->map + ((ulli)(y))*(ulli)(bm)->dy) + #define bm_index(bm, x, y) (&bm_scanline(bm, y)[(x)/BM_WORDBITS]) + #define bm_mask(x) (BM_HIBIT >> ((x) & (BM_WORDBITS-1))) + #define bm_range(x, a) ((int)(x) >= 0 && (int)(x) < (a)) +@@ -43,6 +47,16 @@ + #define BM_INV(bm, x, y) (bm_safe(bm, x, y) ? BM_UINV(bm, x, y) : 0) + #define BM_PUT(bm, x, y, b) (bm_safe(bm, x, y) ? BM_UPUT(bm, x, y, b) : 0) + ++/* allocates memory safely */ ++static inline void* safe_malloc(ulli size) { ++ size_t maxsize = (size_t)-1; ++ if (size > maxsize) { ++ errno = ENOMEM; ++ return NULL; ++ } ++ return malloc((size_t)size); ++} ++ + /* free the given bitmap. Leaves errno untouched. */ + static inline void bm_free(potrace_bitmap_t *bm) { + if (bm) { +@@ -54,16 +68,21 @@ static inline void bm_free(potrace_bitmap_t *bm) { + /* return new un-initialized bitmap. NULL with errno on error */ + static inline potrace_bitmap_t *bm_new(int w, int h) { + potrace_bitmap_t *bm; +- int dy = (w + BM_WORDBITS - 1) / BM_WORDBITS; ++ int dy; ++ ++ if (w % BM_WORDBITS == 0) ++ dy = w / BM_WORDBITS; ++ else ++ dy = (w / BM_WORDBITS) + 1; + +- bm = (potrace_bitmap_t *) malloc(sizeof(potrace_bitmap_t)); ++ bm = (potrace_bitmap_t *)safe_malloc(sizeof(potrace_bitmap_t)); + if (!bm) { + return NULL; + } + bm->w = w; + bm->h = h; + bm->dy = dy; +- bm->map = (potrace_word *) malloc(dy * h * BM_WORDSIZE); ++ bm->map = (potrace_word *)safe_malloc(bm_allocsize(bm) * BM_WORDSIZE); + if (!bm->map) { + free(bm); + return NULL; +@@ -73,7 +92,7 @@ static inline potrace_bitmap_t *bm_new(int w, int h) { + + /* clear the given bitmap. Set all bits to c. */ + static inline void bm_clear(potrace_bitmap_t *bm, int c) { +- memset(bm->map, c ? -1 : 0, bm->dy * bm->h * BM_WORDSIZE); ++ memset(bm->map, c ? -1 : 0, bm_allocsize(bm) * BM_WORDSIZE); + } + + /* duplicate the given bitmap. Return NULL on error with errno set. */ +@@ -82,14 +101,14 @@ static inline potrace_bitmap_t *bm_dup(const potrace_bitmap_t *bm) { + if (!bm1) { + return NULL; + } +- memcpy(bm1->map, bm->map, bm->dy * bm->h * BM_WORDSIZE); ++ memcpy(bm1->map, bm->map, bm_allocsize(bm) * BM_WORDSIZE); + return bm1; + } + + /* invert the given bitmap. */ + static inline void bm_invert(potrace_bitmap_t *bm) { +- int i; +- for (i = 0; i < bm->dy * bm->h; i++) { ++ ulli i; ++ for (i = 0; i < bm_allocsize(bm); i++) { + bm->map[i] ^= BM_ALLBITS; + } + } +diff --git a/src/bitmap_io.c b/src/bitmap_io.c +index 6cfecb1..ea2d188 100644 +--- a/src/bitmap_io.c ++++ b/src/bitmap_io.c +@@ -381,6 +381,16 @@ static int bmp_readint(FILE *f, int n, unsigned int *p) { + return 0; + } + ++/* converts unsigned to signed using 32 bits */ ++static int unsigned_to_signed32(unsigned int x) { ++ unsigned int sign = 0x80000000U; ++ unsigned int mask = 0xFFFFFFFFU; ++ if (sign & x) ++ return -(int)(x ^ mask) - 1; ++ else ++ return (int)x; ++} ++ + /* reset padding boundary */ + static void bmp_pad_reset(void) { + bmp_count = 0; +@@ -478,12 +488,25 @@ static int bm_readbody_bmp(FILE *f, double threshold, potrace_bitmap_t **bmp) { + TRY(bmp_readint(f, 4, &bmpinfo.BlueMask)); + TRY(bmp_readint(f, 4, &bmpinfo.AlphaMask)); + } +- if ((signed int)bmpinfo.h < 0) { +- bmpinfo.h = -bmpinfo.h; ++ int maxdim = 0x7ffffffe; /* 2^31 - 2 */ ++ int sign_h = unsigned_to_signed32(bmpinfo.h); ++ int sign_w = unsigned_to_signed32(bmpinfo.w); ++ if (sign_w < 0 || sign_w > maxdim) { ++ bm_read_error = "incorrect bmp width"; ++ goto format_error; ++ } ++ if (sign_h < -maxdim || sign_h > maxdim) { ++ bm_read_error = "incorrect bmp height"; ++ goto format_error; ++ } ++ if (sign_h < 0) { ++ bmpinfo.h = (unsigned int)(-sign_h); + bmpinfo.topdown = 1; + } else { + bmpinfo.topdown = 0; + } ++ /* now we know that bmpinfo.{w,h} are non-negative ints ++ that fit in int type (cf. bm_new)) */ + } else if (bmpinfo.InfoSize == 12) { + /* old OS/2 format */ + bmpinfo.ctbits = 24; /* sample size in color table */ +@@ -517,7 +540,8 @@ static int bm_readbody_bmp(FILE *f, double threshold, potrace_bitmap_t **bmp) { + + /* color table, present only if bmpinfo.bits <= 8. */ + if (bmpinfo.bits <= 8) { +- coltable = (int *) malloc(bmpinfo.ncolors * sizeof(int)); ++ ulli bytes = (ulli)bmpinfo.ncolors * (ulli)sizeof(int); ++ coltable = (int *)safe_malloc(bytes); + if (!coltable) { + goto std_error; + } diff -Nru potrace-1.11/debian/patches/series potrace-1.11/debian/patches/series --- potrace-1.11/debian/patches/series 2015-03-17 08:16:28.000000000 +0100 +++ potrace-1.11/debian/patches/series 2015-03-17 08:19:09.000000000 +0100 @@ -1 +1,2 @@ typo +0002-Fix-multiple-integer-overflows.patch
signature.asc
Description: Digital signature