Permalink
Browse files

- added integer overflow checks to many memory allocation calls

  • Loading branch information...
Tony Cook
Tony Cook committed Dec 5, 2005
1 parent 9cef844 commit f0960b14ef3c415ec87e69c8636fc81737099b48
Showing with 281 additions and 75 deletions.
  1. +1 −0 Changes
  2. +62 −14 bmp.c
  3. +13 −6 convert.c
  4. +12 −6 datatypes.c
  5. +35 −26 draw.c
  6. +12 −3 error.c
  7. +4 −4 fills.c
  8. +86 −5 filters.c
  9. +9 −3 font.c
  10. +10 −1 img16.c
  11. +11 −2 palimg.c
  12. +12 −1 t/t021sixteen.t
  13. +14 −4 t/t023palette.t
View
@@ -1206,6 +1206,7 @@ Revision history for Perl extension Imager.
- more examples
- add AUTHOR, REVISION.
- add smoke test for nearest_color filter
+- added integer overflow checks to many memory allocation calls
=================================================================
View
76 bmp.c
@@ -413,17 +413,26 @@ write_1bit_data(io_glue *ig, i_img *im) {
unsigned char *out;
int line_size = (im->xsize+7) / 8;
int x, y;
+ int unpacked_size;
/* round up to nearest multiple of four */
line_size = (line_size + 3) / 4 * 4;
if (!write_bmphead(ig, im, 1, line_size * im->ysize))
return 0;
- line = mymalloc(im->xsize + 8);
+ /* this shouldn't be an issue, but let's be careful */
+ unpacked_size = im->xsize + 8;
+ if (unpacked_size < im->xsize) {
+ i_push_error(0, "integer overflow during memory allocation");
+ return 0;
+ }
+ line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
memset(line + im->xsize, 0, 8);
-
- packed = mymalloc(line_size);
+
+ /* size allocated here is always much smaller than xsize, hence
+ can't overflow int */
+ packed = mymalloc(line_size); /* checked 29jun05 tonyc */
memset(packed, 0, line_size);
for (y = im->ysize-1; y >= 0; --y) {
@@ -474,17 +483,26 @@ write_4bit_data(io_glue *ig, i_img *im) {
unsigned char *out;
int line_size = (im->xsize+1) / 2;
int x, y;
+ int unpacked_size;
/* round up to nearest multiple of four */
line_size = (line_size + 3) / 4 * 4;
if (!write_bmphead(ig, im, 4, line_size * im->ysize))
return 0;
- line = mymalloc(im->xsize + 2);
+ /* this shouldn't be an issue, but let's be careful */
+ unpacked_size = im->xsize + 2;
+ if (unpacked_size < im->xsize) {
+ i_push_error(0, "integer overflow during memory allocation");
+ return 0;
+ }
+ line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
memset(line + im->xsize, 0, 2);
- packed = mymalloc(line_size);
+ /* size allocated here is always much smaller than xsize, hence
+ can't overflow int */
+ packed = mymalloc(line_size); /* checked 29jun05 tonyc */
memset(packed, 0, line_size);
for (y = im->ysize-1; y >= 0; --y) {
@@ -522,14 +540,21 @@ write_8bit_data(io_glue *ig, i_img *im) {
i_palidx *line;
int line_size = im->xsize;
int y;
+ int unpacked_size;
/* round up to nearest multiple of four */
line_size = (line_size + 3) / 4 * 4;
if (!write_bmphead(ig, im, 8, line_size * im->ysize))
return 0;
- line = mymalloc(im->xsize + 4);
+ /* this shouldn't be an issue, but let's be careful */
+ unpacked_size = im->xsize + 4;
+ if (unpacked_size < im->xsize) {
+ i_push_error(0, "integer overflow during memory allocation");
+ return 0;
+ }
+ line = mymalloc(unpacked_size); /* checked 29jun05 tonyc */
memset(line + im->xsize, 0, 4);
for (y = im->ysize-1; y >= 0; --y) {
@@ -565,13 +590,20 @@ write_24bit_data(io_glue *ig, i_img *im) {
unsigned char *samples;
int y;
int line_size = 3 * im->xsize;
+
+ /* just in case we implement a direct format with 2bytes/pixel
+ (unlikely though) */
+ if (line_size / 3 != im->xsize) {
+ i_push_error(0, "integer overflow during memory allocation");
+ return 0;
+ }
line_size = (line_size + 3) / 4 * 4;
if (!write_bmphead(ig, im, 24, line_size * im->ysize))
return 0;
chans = im->channels >= 3 ? bgr_chans : grey_chans;
- samples = mymalloc(line_size);
+ samples = mymalloc(line_size); /* checked 29jun05 tonyc */
memset(samples, 0, line_size);
for (y = im->ysize-1; y >= 0; --y) {
i_gsamp(im, 0, im->xsize, y, samples, chans, 3);
@@ -646,6 +678,15 @@ read_1bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
return NULL;
}
+ if (xsize + 8 < xsize) { /* if there was overflow */
+ /* we check with 8 because we allocate that much for the decoded
+ line buffer */
+ i_push_error(0, "integer overflow during memory allocation");
+ return NULL;
+ }
+
+ /* if xsize+7 is ok then (xsize+7)/8 will be and the minor
+ adjustments below won't make it overflow */
line_size = (line_size+3) / 4 * 4;
if (ysize > 0) {
@@ -697,8 +738,8 @@ read_1bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
- packed = mymalloc(line_size);
- line = mymalloc(xsize+8);
+ packed = mymalloc(line_size); /* checked 29jun05 tonyc */
+ line = mymalloc(xsize+8); /* checked 29jun05 tonyc */
while (y != lasty) {
if (ig->readcb(ig, packed, line_size) != line_size) {
myfree(packed);
@@ -751,6 +792,8 @@ read_4bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
int size, i;
long base_offset;
+ /* line_size is going to be smaller than xsize in most cases (and
+ when it's not, xsize is itself small), and hence not overflow */
line_size = (line_size+3) / 4 * 4;
if (ysize > 0) {
@@ -802,10 +845,11 @@ read_4bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
}
if (line_size < 260)
- packed = mymalloc(260);
+ packed = mymalloc(260); /* checked 29jun05 tonyc */
else
- packed = mymalloc(line_size);
- line = mymalloc(xsize+1);
+ packed = mymalloc(line_size); /* checked 29jun05 tonyc */
+ /* xsize won't approach MAXINT */
+ line = mymalloc(xsize+1); /* checked 29jun05 tonyc */
if (compression == BI_RGB) {
i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
while (y != lasty) {
@@ -930,6 +974,10 @@ read_8bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
long base_offset;
line_size = (line_size+3) / 4 * 4;
+ if (line_size < xsize) { /* if it overflowed (unlikely, but check) */
+ i_push_error(0, "integer overflow during memory allocation");
+ return NULL;
+ }
if (ysize > 0) {
y = ysize-1;
@@ -978,7 +1026,7 @@ read_8bit_bmp(io_glue *ig, int xsize, int ysize, int clr_used,
}
}
- line = mymalloc(line_size);
+ line = mymalloc(line_size); /* checked 29jun05 tonyc */
if (compression == BI_RGB) {
i_tags_add(&im->tags, "bmp_compression_name", 0, "BI_RGB", -1, 0);
while (y != lasty) {
@@ -1191,7 +1239,7 @@ read_direct_bmp(io_glue *ig, int xsize, int ysize, int bit_count,
i_push_error(0, "integer overflow calculating buffer size");
return NULL;
}
- line = mymalloc(bytes);
+ line = mymalloc(bytes); /* checked 29jun05 tonyc */
while (y != lasty) {
p = line;
for (x = 0; x < xsize; ++x) {
View
@@ -68,8 +68,9 @@ i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan) {
}
if (im->bits == i_8_bits && src->bits == i_8_bits) {
i_color *vals;
-
- vals = mymalloc(sizeof(i_color) * src->xsize);
+
+ /* we can always allocate a single scanline of i_color */
+ vals = mymalloc(sizeof(i_color) * src->xsize); /* checked 04Jul05 tonyc */
for (y = 0; y < src->ysize; ++y) {
i_glin(src, 0, src->xsize, y, vals);
for (x = 0; x < src->xsize; ++x) {
@@ -97,8 +98,10 @@ i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan) {
}
else {
i_fcolor *vals;
-
- vals = mymalloc(sizeof(i_fcolor) * src->xsize);
+
+ /* we can always allocate a single scanline of i_fcolor
+ for a >8 image */
+ vals = mymalloc(sizeof(i_fcolor) * src->xsize); /* checked 4Jul05 tonyc */
for (y = 0; y < src->ysize; ++y) {
i_glinf(src, 0, src->xsize, y, vals);
for (x = 0; x < src->xsize; ++x) {
@@ -142,7 +145,8 @@ i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan) {
/* just translate the color table */
count = i_colorcount(src);
outcount = i_colorcount(im);
- colors = mymalloc(count * sizeof(i_color));
+ /* color table allocated for image, so it must fit */
+ colors = mymalloc(count * sizeof(i_color)); /* check 04Jul05 tonyc */
i_getcolors(src, 0, colors, count);
for (index = 0; index < count; ++index) {
for (j = 0; j < outchan; ++j) {
@@ -171,7 +175,10 @@ i_convert(i_img *im, i_img *src, float *coeff, int outchan, int inchan) {
i_addcolors(im, colors, count-outcount);
}
/* and copy the indicies */
- vals = mymalloc(sizeof(i_palidx) * im->xsize);
+ /* i_palidx is always unsigned char and will never be bigger than short
+ and since a line of 4-byte i_colors can fit then a line of i_palidx
+ will fit */
+ vals = mymalloc(sizeof(i_palidx) * im->xsize); /* checked 4jul05 tonyc */
for (y = 0; y < im->ysize; ++y) {
i_gpal(src, 0, im->xsize, y, vals);
i_ppal(im, 0, im->xsize, y, vals);
View
@@ -12,9 +12,15 @@
struct i_bitmap*
btm_new(int xsize,int ysize) {
int i;
+ int bytes;
struct i_bitmap *btm;
- btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap));
- btm->data=(char*)mymalloc((xsize*ysize+8)/8);
+ btm=(struct i_bitmap*)mymalloc(sizeof(struct i_bitmap)); /* checked 4jul05 tonyc */
+ bytes = (xsize*ysize+8)/8;
+ if (bytes * 8 / ysize < xsize-1) { /* this is kind of rough */
+ fprintf(stderr, "Integer overflow allocating bitmap %d x %d", xsize, ysize);
+ exit(3);
+ }
+ btm->data=(char*)mymalloc(bytes); /* checked 4jul05 tonyc */
btm->xsize=xsize;
btm->ysize=ysize;
for(i=0;i<(xsize*ysize+8)/8;i++) btm->data[i]=0; /* Is this always needed */
@@ -56,11 +62,11 @@ btm_set(struct i_bitmap *btm,int x,int y) {
struct llink *
llink_new(struct llink* p,int size) {
struct llink *l;
- l = mymalloc(sizeof(struct llink));
+ l = mymalloc(sizeof(struct llink)); /* checked 4jul05 tonyc */
l->n = NULL;
l->p = p;
l->fill = 0;
- l->data = mymalloc(size);
+ l->data = mymalloc(size); /* checked 4jul05 tonyc - depends on caller to llist_push */
return l;
}
@@ -97,7 +103,7 @@ llist_llink_push(struct llist *lst, struct llink *lnk,void *data) {
struct llist *
llist_new(int multip, int ssize) {
struct llist *l;
- l = mymalloc(sizeof(struct llist));
+ l = mymalloc(sizeof(struct llist)); /* checked 4jul05 tonyc */
l->h = NULL;
l->t = NULL;
l->multip = multip;
@@ -198,7 +204,7 @@ octt_new() {
int i;
struct octt *t;
- t=(struct octt*)mymalloc(sizeof(struct octt));
+ t=(struct octt*)mymalloc(sizeof(struct octt)); /* checked 4jul05 tonyc */
for(i=0;i<8;i++) t->t[i]=NULL;
t->cnt=0;
return t;
Oops, something went wrong.

0 comments on commit f0960b1

Please sign in to comment.