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

Attachment: signature.asc
Description: Digital signature

Reply via email to