Version in base suite: 2.83.5+dfsg-5 Base version: blender_2.83.5+dfsg-5 Target version: blender_2.83.5+dfsg-5+deb11u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/b/blender/blender_2.83.5+dfsg-5.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/b/blender/blender_2.83.5+dfsg-5+deb11u1.dsc changelog | 18 ++++ patches/0008-CVE-2022-0544.patch | 127 +++++++++++++++++++++++++++++ patches/0009-CVE-2022-0545.patch | 159 +++++++++++++++++++++++++++++++++++++ patches/0010-CVE-2022-0546.patch | 166 +++++++++++++++++++++++++++++++++++++++ patches/series | 5 + 5 files changed, 475 insertions(+) diff -Nru blender-2.83.5+dfsg/debian/changelog blender-2.83.5+dfsg/debian/changelog --- blender-2.83.5+dfsg/debian/changelog 2020-12-09 14:11:57.000000000 +0000 +++ blender-2.83.5+dfsg/debian/changelog 2022-06-26 10:03:02.000000000 +0000 @@ -1,3 +1,21 @@ +blender (2.83.5+dfsg-5+deb11u1) bullseye-security; urgency=high + + * Non-maintainer upload by the LTS Team. + * CVE-2022-0546 + out-of-bounds heap access due to missing checks in the image loader + could result in denial of service, memory corruption or potentially + code execution + * CVE-2022-0545 + integer overflow while processing 2d images might result in a + write-what-where vulnerability or an out-of-bounds read vulnerability + which could leak sensitive information or achieve code execution + * CVE-2022-0544 + Crafted DDS image files could create an integer underflow in the + DDS loader which leads to an out-of-bounds read and might leak + sensitive information. + + -- Thorsten Alteholz Sun, 26 Jun 2022 12:03:02 +0200 + blender (2.83.5+dfsg-5) unstable; urgency=medium * debian/patches/: patchset updated (Closes: #976378) diff -Nru blender-2.83.5+dfsg/debian/patches/0008-CVE-2022-0544.patch blender-2.83.5+dfsg/debian/patches/0008-CVE-2022-0544.patch --- blender-2.83.5+dfsg/debian/patches/0008-CVE-2022-0544.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.83.5+dfsg/debian/patches/0008-CVE-2022-0544.patch 2022-06-24 14:30:31.000000000 +0000 @@ -0,0 +1,127 @@ +diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp +index 271717f165c..a0a5a75ef8d 100644 +--- a/source/blender/imbuf/intern/dds/Stream.cpp ++++ b/source/blender/imbuf/intern/dds/Stream.cpp +@@ -1,102 +1,117 @@ + /* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + /** \file + * \ingroup imbdds + */ + + #include + + #include // printf + #include // memcpy + + static const char *msg_error_seek = "DDS: trying to seek beyond end of stream (corrupt file?)"; + static const char *msg_error_read = "DDS: trying to read beyond end of stream (corrupt file?)"; + ++inline bool is_read_within_bounds(const Stream &mem, unsigned int cnt) ++{ ++ if (mem.pos >= mem.size) { ++ /* No more data remained in the memory buffer. */ ++ return false; ++ } ++ ++ if (cnt > mem.size - mem.pos) { ++ /* Reading past the memory bounds. */ ++ return false; ++ } ++ ++ return true; ++} ++ + unsigned int Stream::seek(unsigned int p) + { + if (p > size) { + set_failed(msg_error_seek); + } + else { + pos = p; + } + + return pos; + } + + unsigned int mem_read(Stream &mem, unsigned long long &i) + { +- if (mem.pos + 8 > mem.size) { ++ if (!is_read_within_bounds(mem, 8)) { + mem.set_failed(msg_error_seek); + return (0); + } + memcpy(&i, mem.mem + mem.pos, 8); // @@ todo: make sure little endian + mem.pos += 8; + return (8); + } + + unsigned int mem_read(Stream &mem, unsigned int &i) + { +- if (mem.pos + 4 > mem.size) { ++ if (!is_read_within_bounds(mem, 4)) { + mem.set_failed(msg_error_read); + return (0); + } + memcpy(&i, mem.mem + mem.pos, 4); // @@ todo: make sure little endian + mem.pos += 4; + return (4); + } + + unsigned int mem_read(Stream &mem, unsigned short &i) + { +- if (mem.pos + 2 > mem.size) { ++ if (!is_read_within_bounds(mem, 2)) { + mem.set_failed(msg_error_read); + return (0); + } + memcpy(&i, mem.mem + mem.pos, 2); // @@ todo: make sure little endian + mem.pos += 2; + return (2); + } + + unsigned int mem_read(Stream &mem, unsigned char &i) + { +- if (mem.pos + 1 > mem.size) { ++ if (!is_read_within_bounds(mem, 1)) { + mem.set_failed(msg_error_read); + return (0); + } + i = (mem.mem + mem.pos)[0]; + mem.pos += 1; + return (1); + } + + unsigned int mem_read(Stream &mem, unsigned char *i, unsigned int cnt) + { +- if (mem.pos + cnt > mem.size) { ++ if (!is_read_within_bounds(mem, cnt)) { + mem.set_failed(msg_error_read); + return (0); + } + memcpy(i, mem.mem + mem.pos, cnt); + mem.pos += cnt; + return (cnt); + } + + void Stream::set_failed(const char *msg) + { + if (!failed) { + puts(msg); + failed = true; + } + } diff -Nru blender-2.83.5+dfsg/debian/patches/0009-CVE-2022-0545.patch blender-2.83.5+dfsg/debian/patches/0009-CVE-2022-0545.patch --- blender-2.83.5+dfsg/debian/patches/0009-CVE-2022-0545.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.83.5+dfsg/debian/patches/0009-CVE-2022-0545.patch 2022-06-24 14:30:31.000000000 +0000 @@ -0,0 +1,159 @@ +diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c +index 17b485b5171..f02f3e37d6a 100644 +--- a/source/blender/imbuf/intern/rotate.c ++++ b/source/blender/imbuf/intern/rotate.c +@@ -1,119 +1,125 @@ + /* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * rotate.c + */ + + /** \file + * \ingroup imbuf + */ + + #include "BLI_utildefines.h" + + #include "MEM_guardedalloc.h" + + #include "IMB_imbuf.h" + #include "IMB_imbuf_types.h" + #include "imbuf.h" + + void IMB_flipy(struct ImBuf *ibuf) + { +- int x, y; ++ size_t x_size, y_size; + + if (ibuf == NULL) { + return; + } + + if (ibuf->rect) { + unsigned int *top, *bottom, *line; + +- x = ibuf->x; +- y = ibuf->y; ++ x_size = ibuf->x; ++ y_size = ibuf->y; ++ ++ const size_t stride = x_size * sizeof(int); + + top = ibuf->rect; +- bottom = top + ((y - 1) * x); +- line = MEM_mallocN(x * sizeof(int), "linebuf"); ++ bottom = top + ((y_size - 1) * x_size); ++ line = MEM_mallocN(stride, "linebuf"); + +- y >>= 1; ++ y_size >>= 1; + +- for (; y > 0; y--) { +- memcpy(line, top, x * sizeof(int)); +- memcpy(top, bottom, x * sizeof(int)); +- memcpy(bottom, line, x * sizeof(int)); +- bottom -= x; +- top += x; ++ for (; y_size > 0; y_size--) { ++ memcpy(line, top, stride); ++ memcpy(top, bottom, stride); ++ memcpy(bottom, line, stride); ++ bottom -= x_size; ++ top += x_size; + } + + MEM_freeN(line); + } + + if (ibuf->rect_float) { + float *topf = NULL, *bottomf = NULL, *linef = NULL; + +- x = ibuf->x; +- y = ibuf->y; ++ x_size = ibuf->x; ++ y_size = ibuf->y; ++ ++ const size_t stride = x_size * 4 * sizeof(float); + + topf = ibuf->rect_float; +- bottomf = topf + 4 * ((y - 1) * x); +- linef = MEM_mallocN(4 * x * sizeof(float), "linebuff"); ++ bottomf = topf + 4 * ((y_size - 1) * x_size); ++ linef = MEM_mallocN(stride, "linebuf"); + +- y >>= 1; ++ y_size >>= 1; + +- for (; y > 0; y--) { +- memcpy(linef, topf, 4 * x * sizeof(float)); +- memcpy(topf, bottomf, 4 * x * sizeof(float)); +- memcpy(bottomf, linef, 4 * x * sizeof(float)); +- bottomf -= 4 * x; +- topf += 4 * x; ++ for (; y_size > 0; y_size--) { ++ memcpy(linef, topf, stride); ++ memcpy(topf, bottomf, stride); ++ memcpy(bottomf, linef, stride); ++ bottomf -= 4 * x_size; ++ topf += 4 * x_size; + } + + MEM_freeN(linef); + } + } + + void IMB_flipx(struct ImBuf *ibuf) + { + int x, y, xr, xl, yi; + float px_f[4]; + + if (ibuf == NULL) { + return; + } + + x = ibuf->x; + y = ibuf->y; + + if (ibuf->rect) { + for (yi = y - 1; yi >= 0; yi--) { ++ const size_t x_offset = (size_t)x * yi; + for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) { +- SWAP(unsigned int, ibuf->rect[(x * yi) + xr], ibuf->rect[(x * yi) + xl]); ++ SWAP(unsigned int, ibuf->rect[x_offset + xr], ibuf->rect[x_offset + xl]); + } + } + } + + if (ibuf->rect_float) { + for (yi = y - 1; yi >= 0; yi--) { ++ const size_t x_offset = (size_t)x * yi; + for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) { +- memcpy(&px_f, &ibuf->rect_float[((x * yi) + xr) * 4], 4 * sizeof(float)); +- memcpy(&ibuf->rect_float[((x * yi) + xr) * 4], +- &ibuf->rect_float[((x * yi) + xl) * 4], +- 4 * sizeof(float)); +- memcpy(&ibuf->rect_float[((x * yi) + xl) * 4], &px_f, 4 * sizeof(float)); ++ memcpy(&px_f, &ibuf->rect_float[(x_offset + xr) * 4], sizeof(float[4])); ++ memcpy(&ibuf->rect_float[(x_offset + xr) * 4], ++ &ibuf->rect_float[(x_offset + xl) * 4], ++ sizeof(float[4])); ++ memcpy(&ibuf->rect_float[(x_offset + xl) * 4], &px_f, sizeof(float[4])); + } + } + } + } diff -Nru blender-2.83.5+dfsg/debian/patches/0010-CVE-2022-0546.patch blender-2.83.5+dfsg/debian/patches/0010-CVE-2022-0546.patch --- blender-2.83.5+dfsg/debian/patches/0010-CVE-2022-0546.patch 1970-01-01 00:00:00.000000000 +0000 +++ blender-2.83.5+dfsg/debian/patches/0010-CVE-2022-0546.patch 2022-06-24 22:35:06.000000000 +0000 @@ -0,0 +1,166 @@ +Index: blender-2.83.5+dfsg/source/blender/imbuf/intern/radiance_hdr.c +=================================================================== +--- blender-2.83.5+dfsg.orig/source/blender/imbuf/intern/radiance_hdr.c 2022-06-25 00:26:17.317413783 +0200 ++++ blender-2.83.5+dfsg/source/blender/imbuf/intern/radiance_hdr.c 2022-06-25 00:35:03.681975686 +0200 +@@ -77,7 +77,7 @@ + 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--; +@@ -222,7 +222,7 @@ + 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((void *)mem)) { + colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT); +@@ -235,74 +235,92 @@ + break; + } + } +- if (found && (x < (size + 2))) { +- if (sscanf((char *)&mem[x + 1], +- "%79s %d %79s %d", ++ if ((found && (x < (size - 1))) == 0) { ++ /* Data not found! */ ++ return NULL; ++ } ++ ++ 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, + &width) != 4) { + return NULL; +- } ++ } + +- /* find end of this line, data right behind it */ +- ptr = (unsigned char *)strchr((char *)&mem[x + 1], '\n'); +- ptr++; ++ if (width < 1 || height < 1) { ++ return NULL; ++ } + +- if (flags & IB_test) { +- ibuf = IMB_allocImBuf(width, height, 32, 0); +- } +- else { +- ibuf = IMB_allocImBuf(width, height, 32, (flags & IB_rect) | IB_rectfloat); +- } ++ /* 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. */ + +- if (UNLIKELY(ibuf == NULL)) { +- return NULL; +- } +- ibuf->ftype = IMB_FTYPE_RADHDR; ++ /* find end of this line, data right behind it */ ++ ptr = (const unsigned char *)strchr((const char *)&mem[x], '\n'); ++ if (ptr == NULL || ptr >= mem_eof) { ++ return NULL; ++ } + +- if (flags & IB_alphamode_detect) { +- ibuf->flags |= IB_alphamode_premul; +- } ++ ptr++; + +- if (flags & IB_test) { +- return ibuf; +- } ++ if (flags & IB_test) { ++ ibuf = IMB_allocImBuf(width, height, 32, 0); ++ } ++ else { ++ ibuf = IMB_allocImBuf(width, height, 32, (flags & IB_rect) | IB_rectfloat); ++ } + +- /* read in and decode the actual data */ +- sline = (RGBE *)MEM_mallocN(sizeof(*sline) * width, __func__); +- rect_float = ibuf->rect_float; ++ if (UNLIKELY(ibuf == NULL)) { ++ return NULL; ++ } ++ ibuf->ftype = IMB_FTYPE_RADHDR; + +- for (size_t y = 0; y < height; y++) { +- ptr = freadcolrs(sline, ptr, width, mem_eof); +- if (ptr == NULL) { +- printf( +- "WARNING! HDR decode error, image may be just truncated, or completely wrong...\n"); +- break; +- } +- for (x = 0; x < width; x++) { +- /* convert to ldr */ +- RGBE2FLOAT(sline[x], fcol); +- *rect_float++ = fcol[RED]; +- *rect_float++ = fcol[GRN]; +- *rect_float++ = fcol[BLU]; +- *rect_float++ = 1.0f; +- } +- } +- MEM_freeN(sline); +- if (oriY[0] == '-') { +- IMB_flipy(ibuf); +- } ++ if (flags & IB_alphamode_detect) { ++ ibuf->flags |= IB_alphamode_premul; ++ } + +- if (flags & IB_rect) { +- IMB_rect_from_float(ibuf); ++ if (flags & IB_test) { ++ return ibuf; ++ } ++ ++ /* read in and decode the actual data */ ++ sline = (RGBE *)MEM_mallocN(sizeof(*sline) * width, __func__); ++ rect_float = ibuf->rect_float; ++ ++ for (size_t y = 0; y < height; y++) { ++ ptr = freadcolrs(sline, ptr, width, mem_eof); ++ if (ptr == NULL) { ++ printf( ++ "WARNING! HDR decode error, image may be just truncated, or completely wrong...\n"); ++ break; ++ } ++ for (x = 0; x < width; x++) { ++ /* convert to ldr */ ++ RGBE2FLOAT(sline[x], fcol); ++ *rect_float++ = fcol[RED]; ++ *rect_float++ = fcol[GRN]; ++ *rect_float++ = fcol[BLU]; ++ *rect_float++ = 1.0f; + } ++ } ++ MEM_freeN(sline); ++ if (oriY[0] == '-') { ++ IMB_flipy(ibuf); ++ } + +- return ibuf; ++ if (flags & IB_rect) { ++ IMB_rect_from_float(ibuf); + } +- // else printf("Data not found!\n"); ++ ++ return ibuf; + } +- // else printf("Not a valid radiance HDR file!\n"); + + return NULL; + } diff -Nru blender-2.83.5+dfsg/debian/patches/series blender-2.83.5+dfsg/debian/patches/series --- blender-2.83.5+dfsg/debian/patches/series 2020-12-09 14:00:07.000000000 +0000 +++ blender-2.83.5+dfsg/debian/patches/series 2022-06-24 14:31:13.000000000 +0000 @@ -5,3 +5,8 @@ defaultc++14.patch 0006-fix_FTBFS_with_python3.9.patch 0007-BPY_thread_save_crashes_against_Py3.9.patch + +0008-CVE-2022-0544.patch +0009-CVE-2022-0545.patch +0010-CVE-2022-0546.patch +