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:
parent
fce4b94bb2
commit
1f9edb0b84
2 changed files with 5 additions and 10 deletions
12
lib/quirc.c
12
lib/quirc.c
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue