Fix T89542: Crash when loading certain .hdr files
The direct cause of the bug in question was passing in the raw memory buffer to sscanf. It should be called with a null-terminated buffer; which isn't guaranteed when blindly trusting the file data. When attempting to fuzz this code path, a variety of other crashes were discovered and fixed. Differential Revision: https://developer.blender.org/D11952
This commit is contained in:
parent
87b77a97b9
commit
1ee4e6bf31
Notes:
blender-bot
2023-02-14 02:08:37 +01:00
Referenced by issue #88449: Blender LTS: Maintenance Task 2.93 Referenced by issue #88449, Blender LTS: Maintenance Task 2.93 Referenced by issue #94572, Out-of-bounds memory access due to malformed HDR image file Referenced by issue #89542, Blender Crashes to Desktop when viewing thumbnail of a certain HDRI
|
@ -77,7 +77,7 @@ static const unsigned char *oldreadcolrs(RGBE *scan,
|
|||
scan[0][BLU] = *mem++;
|
||||
scan[0][EXP] = *mem++;
|
||||
if (scan[0][RED] == 1 && scan[0][GRN] == 1 && scan[0][BLU] == 1) {
|
||||
for (i = scan[0][EXP] << rshift; i > 0; i--) {
|
||||
for (i = scan[0][EXP] << rshift; i > 0 && len > 0; i--) {
|
||||
COPY_RGBE(scan[-1], scan[0]);
|
||||
scan++;
|
||||
len--;
|
||||
|
@ -227,7 +227,7 @@ struct ImBuf *imb_loadhdr(const unsigned char *mem,
|
|||
int found = 0;
|
||||
int width = 0, height = 0;
|
||||
const unsigned char *ptr, *mem_eof = mem + size;
|
||||
char oriY[80], oriX[80];
|
||||
char oriY[3], oriX[3];
|
||||
|
||||
if (!imb_is_a_hdr(mem, size)) {
|
||||
return NULL;
|
||||
|
@ -244,13 +244,19 @@ struct ImBuf *imb_loadhdr(const unsigned char *mem,
|
|||
}
|
||||
}
|
||||
|
||||
if ((found && (x < (size + 2))) == 0) {
|
||||
if ((found && (x < (size - 1))) == 0) {
|
||||
/* Data not found! */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sscanf((const char *)&mem[x + 1],
|
||||
"%79s %d %79s %d",
|
||||
x++;
|
||||
|
||||
/* sscanf requires a null-terminated buffer argument */
|
||||
char buf[32] = {0};
|
||||
memcpy(buf, &mem[x], MIN2(sizeof(buf) - 1, size - x));
|
||||
|
||||
if (sscanf(buf,
|
||||
"%2s %d %2s %d",
|
||||
(char *)&oriY,
|
||||
&height,
|
||||
(char *)&oriX,
|
||||
|
@ -258,8 +264,18 @@ struct ImBuf *imb_loadhdr(const unsigned char *mem,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (width < 1 || height < 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Checking that width x height does not extend past mem_eof is not easily possible
|
||||
* since the format uses RLE compression. Can cause excessive memory allocation to occur. */
|
||||
|
||||
/* find end of this line, data right behind it */
|
||||
ptr = (const unsigned char *)strchr((const char *)&mem[x + 1], '\n');
|
||||
ptr = (const unsigned char *)strchr((const char *)&mem[x], '\n');
|
||||
if (ptr == NULL || ptr >= mem_eof) {
|
||||
return NULL;
|
||||
}
|
||||
ptr++;
|
||||
|
||||
if (flags & IB_test) {
|
||||
|
|
Loading…
Reference in New Issue