Fix a potential use-after-free on quirc_resize failure.

Before this patch, in the event of `q->image` reallocation success but
`q->pixels` failure, `q->image` would point to a freed memory.

After this patch, once quirc_resize() returns, `q->image` consistently
point to a memory address that can be freed.

There is still an inconsistency left in the example codepath: `q->{h,w}`
would hold the "old" values, while `q->image` allocated size would be
based in the requested width/height; hence the comment update about the
state of the QR-code recognizer (it should only be passed to
quirc_destroy()).
This commit is contained in:
Alexandre Perrin 2017-06-07 19:37:14 +02:00
parent fce4b94bb2
commit 1f9edb0b84
2 changed files with 5 additions and 10 deletions

View file

@ -36,8 +36,7 @@ struct quirc *quirc_new(void)
void quirc_destroy(struct quirc *q) void quirc_destroy(struct quirc *q)
{ {
if (q->image) free(q->image);
free(q->image);
if (sizeof(*q->image) != sizeof(*q->pixels)) if (sizeof(*q->image) != sizeof(*q->pixels))
free(q->pixels); free(q->pixels);
@ -47,23 +46,18 @@ void quirc_destroy(struct quirc *q)
int quirc_resize(struct quirc *q, int w, int h) int quirc_resize(struct quirc *q, int w, int h)
{ {
uint8_t *new_image = realloc(q->image, w * h); uint8_t *new_image = realloc(q->image, w * h);
if (!new_image) if (!new_image)
return -1; return -1;
q->image = new_image;
if (sizeof(*q->image) != sizeof(*q->pixels)) { if (sizeof(*q->image) != sizeof(*q->pixels)) {
size_t new_size = w * h * sizeof(quirc_pixel_t); size_t new_size = w * h * sizeof(quirc_pixel_t);
quirc_pixel_t *new_pixels = realloc(q->pixels, new_size); quirc_pixel_t *new_pixels = realloc(q->pixels, new_size);
if (!new_pixels)
if (!new_pixels) {
free(new_image);
return -1; return -1;
}
q->pixels = new_pixels; q->pixels = new_pixels;
} }
q->image = new_image;
q->w = w; q->w = w;
q->h = h; q->h = h;

View file

@ -40,7 +40,8 @@ void quirc_destroy(struct quirc *q);
* specified before codes can be analyzed. * specified before codes can be analyzed.
* *
* This function returns 0 on success, or -1 if sufficient memory could * This function returns 0 on success, or -1 if sufficient memory could
* not be allocated. * not be allocated. On failure the QR-code recognizer should not be
* used and is expected to be given to quirc_destroy() for cleanup.
*/ */
int quirc_resize(struct quirc *q, int w, int h); int quirc_resize(struct quirc *q, int w, int h);