Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Yurkovich <jesse.y@gmail.com>2022-01-12 07:48:32 +0300
committerPhilipp Oeser <info@graphics-engineer.com>2022-02-21 12:54:40 +0300
commit1ee4e6bf31ff32f87f9cd1eafa548d6811794380 (patch)
tree89977a4e9a623d8727349986ce4ad037055193e6
parent87b77a97b947a3d799fc5aa6ac7d2c5e5606109b (diff)
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
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index 94b2a62aa26..90972da7da1 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -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) {