Talos security advisory for Blender product (TALOS-2017-0451) #52924

Closed
opened 2017-09-27 20:20:08 +02:00 by Talos Security Advisory · 43 comments

System Information
Operating system and graphics card

Blender Version
Tested Versions - Blender v2.78c (32-bit)

Short description of error Files sent via separate communication including report
Exact steps for others to reproduce the error
Based on a (as simple as possible) attached .blend file with minimum amount of steps
TALOS-2017-0451
TALOS-2017-0452
TALOS-2017-0453
TALOS-2017-0454
TALOS-2017-0455
TALOS-2017-0456
TALOS-2017-0457

**System Information** Operating system and graphics card **Blender Version** Tested Versions - Blender v2.78c (32-bit) **Short description of error** Files sent via separate communication including report **Exact steps for others to reproduce the error** Based on a (as simple as possible) attached .blend file with minimum amount of steps TALOS-2017-0451 TALOS-2017-0452 TALOS-2017-0453 TALOS-2017-0454 TALOS-2017-0455 TALOS-2017-0456 TALOS-2017-0457

Changed status to: 'Open'

Changed status to: 'Open'

Added subscriber: @regiwils

Added subscriber: @regiwils
Member

Added subscriber: @LazyDodo

Added subscriber: @LazyDodo
Sergey Sharybin was assigned by Ray molenkamp 2017-09-27 20:22:51 +02:00
Member

I guess there's some internal emails for you to look at?

I guess there's some internal emails for you to look at?
Member

Added subscriber: @Ton

Added subscriber: @Ton
Member

I have all the information in a private mail. It's quite interesting and elaborately documented.
It also includes a .blend that would (i guess) create an exploit. Will send that to the hardcore devs here in private

I have all the information in a private mail. It's quite interesting and elaborately documented. It also includes a .blend that would (i guess) create an exploit. Will send that to the hardcore devs here in private

Thanks for your response/review. Look forward to hearing any feedback/new developments.

Thanks for your response/review. Look forward to hearing any feedback/new developments.
Member

Just for everyone's interest, this is part of the report in the mail.

2017-MM-DD (published patch date)
TALOS-2017-0452
CVE-2017-12100

Blender multires_load_old_dm base vertex map Integer Overflow Code Execution Vulnerability

Summary

An exploitable integer overflow exists in the multires_load_old_dm functionality of the Blender open-source 3d creation suite v2.78c. A specially crafted .blend file can cause an integer overflow resulting in a buffer overflow which can allow for code execution under the context of the application. An attacker can convince a user to open a .blend file in order to trigger this vulnerability.

Tested Versions

Blender v2.78c (32-bit)

Product URLs

http:*www.blender.org
git:*git.blender.org/blender.git

CVSSv3 Score

8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-190 - Integer Overflow or Wraparound

Details

Blender is a professional, open-source 3d computer graphics application. It is used for creating animated films, visual effects, art, 3d printed applications, and video games. It is also capable of doing minimalistic video editing and sequencing as needed by the user. There are various features that it provides which allow for a user to perform a multitude of actions as required by a particular project.

This vulnerability occurs when loading an old Multires structure from a Mesh into a newer format. When handling an older version of a .blend file, the application will call a function to initialize the base vertices used for multi-resolution meshes. When allocating space for these vertices, the application will use the total number of vertices in some arithmetic which can overflow. This will then be used to perform an allocation which can be made to be smaller than the total number of vertices used to initialize an array. When initializing this array, the application can then write outside the bounds of the array which causes a heap-based buffer overflow.

After loading all the basic-blocks in a file, the application will call the blo_do_versions_250 function. This function will check the version of the file as specified in the FileGlobals structure and use it to perform various transformations on the data-structures in the file in order to provide backwards compatibility. At - [x], the application will check if the version is less than or equal to 250 and that the subversionfile field is less than 1 (exclusive). After this is verified, the application will iterate through all the Object data-blocks in the file and at - [x] check to see if its type field is set to OB_MESH(1). If so, then the object and its associated Mesh that's pointed to by the data field is then passed the multires_load_old function at [3].

  source/blender/blenloader/intern/versioning_250.c:732
  void blo_do_versions_250(FileData *fd, Library *lib, Main *main)
  {
  ...
      if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 1)) {    // [1]
  ...
          for (ob = main->object.first; ob; ob = ob->id.next) {
  ...
              if (ob->type == OB_MESH) {                                                          // [2]
                  Mesh *me = blo_do_versions_newlibadr(fd, lib, ob->data);
                  void *olddata = ob->data;
                  ob->data = me;
  ...
                  if (me && me->id.lib == NULL && me->mr && me->mr->level_count > 1) {
                      multires_load_old(ob, me);                                                  // [3]
                  }
                  ob->data = olddata;
              }
  ...

Once inside the multires_load_old function, at - [x] the application will assign a pointer to a Multires structure from the Mesh structure's mr field. Dereferencing the levels field results in a MultiresData structure that contains a number of fields that are re-assigned to the Mesh structure. In these fields, the value of totvert is significant to note as it is used to trigger this vulnerability. Once re-assigning the fields at - [x], the application will then convert the faces defined by the Mesh into polygons which is then used to create a DerivedMesh object. This and the Mesh itself are passed as arguments to multires_load_old_dm at [6].

  source/blender/blenkernel/intern/multires.c:2064
  void multires_load_old(Object *ob, Mesh *me)
  {
  ...
      lvl = me->mr->levels.first;                     // [4]
  ...
      me->totvert = lvl->totvert;
      me->totedge = lvl->totedge;
      me->totface = lvl->totface;
  ...
      multires_load_old_vcols(me);
      multires_load_old_face_flags(me);
      /* multiresModifier_subdivide (actually, multires_subdivide) expects polys, not tessfaces! */
      BKE_mesh_convert_mfaces_to_mpolys(me);          // [5]
  ...
      orig = CDDM_from_mesh(me);
  ...
      dm = multires_make_derived_from_derived(orig, mmd, ob, 0);
      multires_load_old_dm(dm, me, mmd->totlvl + 1);  // [6]
  ...

The multires_load_old_dm function is responsible for converting the old Multires-formatted structure into its newer format. At - [x], the application will assign the mr field belonging to the Mesh to a pointer. At - [x], the application will extract the total number of vertices defined within the DerivedMesh that was made earlier using the fields from the Mesh structure and assign the result to the totvert variable. Once this is done, at - [x] the application will use this variable to calculate a product using the size of an int (4) with the number of vertices and pass this as a size for an allocation. If the result of this arithmetic has a result larger than a 32-bit number, then this allocation will overflow resulting in an undersized buffer. At [10], when the application attempts to initialize this array, the application will use the difference between the total number of vertices in the first MultiresData and the total number of vertices in the second MultiresData from the file to write into the array. During this, an out-of-bounds write can occur resulting in a heap-based buffer overflow. Within the provided proof-of-concept, the value used for the level 1 totvert field is 1. This type of overwrite can allow for code execution within the context of the application.

  source/blender/blenkernel/intern/multires.c:1851
  static void multires_load_old_dm(DerivedMesh *dm, Mesh *me, int totlvl)
  {
      MultiresLevel *lvl, *lvl1;
      Multires *mr = me->mr;                                          // [7]
  ...
      vsrc = mr->verts;
      vdst = dm->getVertArray(dm);
      totvert = (unsigned int)dm->getNumVerts(dm);                    // [8]
      vvmap = MEM_callocN(sizeof(int) * totvert, "multires vvmap");   // [9]
      lvl1 = mr->levels.first;
      /* Load base verts */
      for (i = 0; i < lvl1->totvert; ++i) {
          vvmap[totvert - lvl1->totvert + i] = src;                   // [10]
          src++;
      }

Crash Information

  (2a50.2a9c): Access violation - code c0000005 (first chance)
  First chance exceptions are reported before any exception handling.
  This exception may be expected and handled.
  eax=00000001 ebx=00000001 ecx=00000002 edx=328d6ffc esi=329c6fd4 edi=02da1710
  eip=014aa00b esp=002fe8f8 ebp=002fe968 iopl=0         nv up ei pl nz na po cy
  cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010203
  blender!PyInit_mathutils_noise_types+0x28b58b:
014aa00b 891c82          mov     dword ptr [edx+eax*4],ebx ds:002b:328d7000=????????

0:000> !heap -p -a @edx
      address 328d6ffc found in
      _DPH_HEAP_ROOT @ 4a1000
      in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                328612a4:         328d6ff8                4 -         328d6000             2000
    6b7e8d9c verifier!AVrfDebugPageHeapAllocate+0x0000023c
    77d6fb79 ntdll!RtlDebugAllocateHeap+0x00000032
    77d09a73 ntdll!RtlpAllocateHeap+0x0003914a
    77cd0b43 ntdll!RtlAllocateHeap+0x0000014c
    0292f5b3 blender!xmlGetThreadId+0x0000c0b3
    02915fc1 blender!xmlListWalk+0x00223241
    017cd129 blender!osl_texture_set_swrap_code+0x00171e99
    014a9fe2 blender!PyInit_mathutils_noise_types+0x0028b562
    014a9dbb blender!PyInit_mathutils_noise_types+0x0028b33b
    013681b4 blender!PyInit_mathutils_noise_types+0x00149734
    013582f0 blender!PyInit_mathutils_noise_types+0x00139870
    0134ee74 blender!PyInit_mathutils_noise_types+0x001303f4
    01361989 blender!PyInit_mathutils_noise_types+0x00142f09
    01401fab blender!PyInit_mathutils_noise_types+0x001e352b
    00e6ddca blender!xmlFileMatch+0x000078fa
    00e6e88f blender!xmlFileMatch+0x000083bf
    00e6f7b1 blender!xmlFileMatch+0x000092e1
    00e7bd3f blender!xmlFileMatch+0x0001586f
    00e7c8c5 blender!xmlFileMatch+0x000163f5
    00e7c4a6 blender!xmlFileMatch+0x00015fd6
    00e7abfa blender!xmlFileMatch+0x0001472a
    00e6c583 blender!xmlFileMatch+0x000060b3
    00e69b1b blender!xmlFileMatch+0x0000364b
    0290a125 blender!xmlListWalk+0x002173a5
    75f7919f KERNEL32!BaseThreadInitThunk+0x0000000e
    77cda8cb ntdll!__RtlUserThreadStart+0x00000020
    77cda8a1 ntdll!_RtlUserThreadStart+0x0000001b

0:000> lm a blender.exe
  Browse full module list
  start    end        module name
00cd0000 04638000   blender  C (export symbols)       blender.exe

Exploit Proof-of-Concept

Included with this advisory is a generator for the vulnerability. This proof-of-concept requires python and takes a single-argument which is the filename to write the .blend file to.

  $ python poc.py.zip $FILENAME.blend

To trigger the vulnerability, one can simply open the file or use it as a library. It can also be passed as an argument to the blender executable.

  $ /path/to/blender.exe $FILENAME.blend

Mitigation

In order to mitigate this vulnerability, it is recommended to not use untrusted blender files.

Credit

Discovered by a member of Cisco Talos.
http://talosintelligence.com/vulnerability-reports/

Timeline

YYYY-MM-DD - Vendor Disclosure
YYYY-MM-DD - Public Release

Just for everyone's interest, this is part of the report in the mail. 2017-MM-DD (published patch date) TALOS-2017-0452 CVE-2017-12100 Blender multires_load_old_dm base vertex map Integer Overflow Code Execution Vulnerability ### Summary An exploitable integer overflow exists in the `multires_load_old_dm` functionality of the Blender open-source 3d creation suite v2.78c. A specially crafted .blend file can cause an integer overflow resulting in a buffer overflow which can allow for code execution under the context of the application. An attacker can convince a user to open a .blend file in order to trigger this vulnerability. ### Tested Versions Blender v2.78c (32-bit) ### Product URLs [http:*www.blender.org](http:*www.blender.org) [git:*git.blender.org/blender.git](git:*git.blender.org/blender.git) ### CVSSv3 Score 8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H ### CWE CWE-190 - Integer Overflow or Wraparound ### Details Blender is a professional, open-source 3d computer graphics application. It is used for creating animated films, visual effects, art, 3d printed applications, and video games. It is also capable of doing minimalistic video editing and sequencing as needed by the user. There are various features that it provides which allow for a user to perform a multitude of actions as required by a particular project. This vulnerability occurs when loading an old `Multires` structure from a `Mesh` into a newer format. When handling an older version of a .blend file, the application will call a function to initialize the base vertices used for multi-resolution meshes. When allocating space for these vertices, the application will use the total number of vertices in some arithmetic which can overflow. This will then be used to perform an allocation which can be made to be smaller than the total number of vertices used to initialize an array. When initializing this array, the application can then write outside the bounds of the array which causes a heap-based buffer overflow. After loading all the basic-blocks in a file, the application will call the `blo_do_versions_250` function. This function will check the version of the file as specified in the `FileGlobals` structure and use it to perform various transformations on the data-structures in the file in order to provide backwards compatibility. At - [x], the application will check if the version is less than or equal to 250 and that the `subversionfile` field is less than 1 (exclusive). After this is verified, the application will iterate through all the `Object` data-blocks in the file and at - [x] check to see if its `type` field is set to `OB_MESH(1)`. If so, then the object and its associated `Mesh` that's pointed to by the `data` field is then passed the `multires_load_old` function at [3]. ``` source/blender/blenloader/intern/versioning_250.c:732 void blo_do_versions_250(FileData *fd, Library *lib, Main *main) { ... if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 1)) { // [1] ... for (ob = main->object.first; ob; ob = ob->id.next) { ... if (ob->type == OB_MESH) { // [2] Mesh *me = blo_do_versions_newlibadr(fd, lib, ob->data); void *olddata = ob->data; ob->data = me; ... if (me && me->id.lib == NULL && me->mr && me->mr->level_count > 1) { multires_load_old(ob, me); // [3] } ``` ``` ob->data = olddata; } ... ``` Once inside the `multires_load_old` function, at - [x] the application will assign a pointer to a `Multires` structure from the `Mesh` structure's `mr` field. Dereferencing the `levels` field results in a `MultiresData` structure that contains a number of fields that are re-assigned to the `Mesh` structure. In these fields, the value of `totvert` is significant to note as it is used to trigger this vulnerability. Once re-assigning the fields at - [x], the application will then convert the faces defined by the `Mesh` into polygons which is then used to create a `DerivedMesh` object. This and the `Mesh` itself are passed as arguments to `multires_load_old_dm` at [6]. ``` source/blender/blenkernel/intern/multires.c:2064 void multires_load_old(Object *ob, Mesh *me) { ... lvl = me->mr->levels.first; // [4] ... me->totvert = lvl->totvert; me->totedge = lvl->totedge; me->totface = lvl->totface; ... multires_load_old_vcols(me); multires_load_old_face_flags(me); ``` ``` /* multiresModifier_subdivide (actually, multires_subdivide) expects polys, not tessfaces! */ BKE_mesh_convert_mfaces_to_mpolys(me); // [5] ... orig = CDDM_from_mesh(me); ... dm = multires_make_derived_from_derived(orig, mmd, ob, 0); ``` ``` multires_load_old_dm(dm, me, mmd->totlvl + 1); // [6] ... ``` The `multires_load_old_dm` function is responsible for converting the old `Multires`-formatted structure into its newer format. At - [x], the application will assign the `mr` field belonging to the `Mesh` to a pointer. At - [x], the application will extract the total number of vertices defined within the `DerivedMesh` that was made earlier using the fields from the `Mesh` structure and assign the result to the `totvert` variable. Once this is done, at - [x] the application will use this variable to calculate a product using the size of an int (4) with the number of vertices and pass this as a size for an allocation. If the result of this arithmetic has a result larger than a 32-bit number, then this allocation will overflow resulting in an undersized buffer. At [10], when the application attempts to initialize this array, the application will use the difference between the total number of vertices in the first `MultiresData` and the total number of vertices in the second `MultiresData` from the file to write into the array. During this, an out-of-bounds write can occur resulting in a heap-based buffer overflow. Within the provided proof-of-concept, the value used for the level 1 `totvert` field is 1. This type of overwrite can allow for code execution within the context of the application. ``` source/blender/blenkernel/intern/multires.c:1851 static void multires_load_old_dm(DerivedMesh *dm, Mesh *me, int totlvl) { MultiresLevel *lvl, *lvl1; Multires *mr = me->mr; // [7] ... vsrc = mr->verts; vdst = dm->getVertArray(dm); totvert = (unsigned int)dm->getNumVerts(dm); // [8] vvmap = MEM_callocN(sizeof(int) * totvert, "multires vvmap"); // [9] ``` ``` lvl1 = mr->levels.first; /* Load base verts */ for (i = 0; i < lvl1->totvert; ++i) { vvmap[totvert - lvl1->totvert + i] = src; // [10] src++; } ``` ### Crash Information ``` (2a50.2a9c): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=00000001 ebx=00000001 ecx=00000002 edx=328d6ffc esi=329c6fd4 edi=02da1710 eip=014aa00b esp=002fe8f8 ebp=002fe968 iopl=0 nv up ei pl nz na po cy cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010203 blender!PyInit_mathutils_noise_types+0x28b58b: ``` 014aa00b 891c82 mov dword ptr [edx+eax*4],ebx ds:002b:328d7000=???????? 0:000> !heap -p -a @edx ``` address 328d6ffc found in _DPH_HEAP_ROOT @ 4a1000 in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize) ``` 328612a4: 328d6ff8 4 - 328d6000 2000 6b7e8d9c verifier!AVrfDebugPageHeapAllocate+0x0000023c 77d6fb79 ntdll!RtlDebugAllocateHeap+0x00000032 77d09a73 ntdll!RtlpAllocateHeap+0x0003914a 77cd0b43 ntdll!RtlAllocateHeap+0x0000014c 0292f5b3 blender!xmlGetThreadId+0x0000c0b3 02915fc1 blender!xmlListWalk+0x00223241 017cd129 blender!osl_texture_set_swrap_code+0x00171e99 014a9fe2 blender!PyInit_mathutils_noise_types+0x0028b562 014a9dbb blender!PyInit_mathutils_noise_types+0x0028b33b 013681b4 blender!PyInit_mathutils_noise_types+0x00149734 013582f0 blender!PyInit_mathutils_noise_types+0x00139870 0134ee74 blender!PyInit_mathutils_noise_types+0x001303f4 01361989 blender!PyInit_mathutils_noise_types+0x00142f09 01401fab blender!PyInit_mathutils_noise_types+0x001e352b 00e6ddca blender!xmlFileMatch+0x000078fa 00e6e88f blender!xmlFileMatch+0x000083bf 00e6f7b1 blender!xmlFileMatch+0x000092e1 00e7bd3f blender!xmlFileMatch+0x0001586f 00e7c8c5 blender!xmlFileMatch+0x000163f5 00e7c4a6 blender!xmlFileMatch+0x00015fd6 00e7abfa blender!xmlFileMatch+0x0001472a 00e6c583 blender!xmlFileMatch+0x000060b3 00e69b1b blender!xmlFileMatch+0x0000364b 0290a125 blender!xmlListWalk+0x002173a5 75f7919f KERNEL32!BaseThreadInitThunk+0x0000000e 77cda8cb ntdll!__RtlUserThreadStart+0x00000020 77cda8a1 ntdll!_RtlUserThreadStart+0x0000001b 0:000> lm a blender.exe ``` Browse full module list start end module name ``` 00cd0000 04638000 blender C (export symbols) blender.exe ### Exploit Proof-of-Concept Included with this advisory is a generator for the vulnerability. This proof-of-concept requires python and takes a single-argument which is the filename to write the .blend file to. ``` $ python poc.py.zip $FILENAME.blend ``` To trigger the vulnerability, one can simply open the file or use it as a library. It can also be passed as an argument to the blender executable. ``` $ /path/to/blender.exe $FILENAME.blend ``` ### Mitigation In order to mitigate this vulnerability, it is recommended to not use untrusted blender files. ### Credit Discovered by a member of Cisco Talos. http://talosintelligence.com/vulnerability-reports/ ### Timeline YYYY-MM-DD - Vendor Disclosure YYYY-MM-DD - Public Release

Added subscriber: @ideasman42

Added subscriber: @ideasman42

Any reason to keep both open? #52654

Any reason to keep both open? #52654

There are a total of 19 issues outstanding. Are there any additional updates for the following:
TALOS-2017-0452
TALOS-2017-0453
TALOS-2017-0454
TALOS-2017-0455
TALOS-2017-0456
TALOS-2017-0457
TALOS-2017-0413
TALOS-2017-0433
TALOS-2017-0434
TALOS-2017-0425
TALOS-2017-0406
TALOS-2017-0407
TALOS-2017-0408
TALOS-2017-0409
TALOS-2017-0410
TALOS-2017-0411
TALOS-2017-0412
TALOS-2017-0413
TALOS-2017-0414
TALOS-2017-0415

There are a total of 19 issues outstanding. Are there any additional updates for the following: TALOS-2017-0452 TALOS-2017-0453 TALOS-2017-0454 TALOS-2017-0455 TALOS-2017-0456 TALOS-2017-0457 TALOS-2017-0413 TALOS-2017-0433 TALOS-2017-0434 TALOS-2017-0425 TALOS-2017-0406 TALOS-2017-0407 TALOS-2017-0408 TALOS-2017-0409 TALOS-2017-0410 TALOS-2017-0411 TALOS-2017-0412 TALOS-2017-0413 TALOS-2017-0414 TALOS-2017-0415
Member

The Cisco team keeps mailing me in private about this. I really don't mind a public discussion.

I wrote:

The discussion on this topic can be done in public.
What I heard however, is that the vulnerability is an extreme theoritical case, not something that would happen in an end-user case.

Cisco reply:

All 21 vulnerabilities that we reported have proof of concepts that trigger the vulnerability and result in a crash, I would say that's pretty far from theoretical. Obviously an attacker would need to do some more work to turn the crashes
into an actual exploit that executes code, but that is not simply theoretical.

My reply:

Sorry for being unclear. I mean that the situations are not practical; as in, created in a practical situation of using Blender.
The vulnerabilities are "theoretical" as in "unlikely to happen, only by purposed sabotage".

That being said, it's not something we ignore, but the investment of resources (using volunteers?!) in fixing this, would not really justify the benefits.
Would you help us fixing this?

The Cisco team keeps mailing me in private about this. I really don't mind a public discussion. I wrote: > The discussion on this topic can be done in public. > What I heard however, is that the vulnerability is an extreme theoritical case, not something that would happen in an end-user case. Cisco reply: > All 21 vulnerabilities that we reported have proof of concepts that trigger the vulnerability and result in a crash, I would say that's pretty far from theoretical. Obviously an attacker would need to do some more work to turn the crashes > into an actual exploit that executes code, but that is not simply theoretical. My reply: > Sorry for being unclear. I mean that the situations are not practical; as in, created in a practical situation of using Blender. > The vulnerabilities are "theoretical" as in "unlikely to happen, only by purposed sabotage". > That being said, it's not something we ignore, but the investment of resources (using volunteers?!) in fixing this, would not really justify the benefits. > Would you help us fixing this?

Added subscriber: @yyounan

Added subscriber: @yyounan

So exploits are unlikely to be created accidentally by using Blender. What we're saying is that if an attacker purposefully creates a malicious file that a user then loads, that user could be compromised. The vulnerabilities exist not only in .blend files, but also in BMP, TIFF and other file formats supported by Blender.

So exploits are unlikely to be created accidentally by using Blender. What we're saying is that if an attacker purposefully creates a malicious file that a user then loads, that user could be compromised. The vulnerabilities exist not only in .blend files, but also in BMP, TIFF and other file formats supported by Blender.

Added subscriber: @brecht

Added subscriber: @brecht

Realistically, Blender is not well protected against these kinds of attacks, and the same is true for other CG software (often you can run arbitrary embedded scripts on file load, which Blender at least prevents). Anyone capable of exploiting these reported vulnerabilities can find 10 more in Blender and its library dependencies. As far as I'm concerned, opening a file with Blender should be considered like opening a file with the Python interpreter, you have the trust to the source it is coming from.

CG artists might not be aware of this and that's a problem, but fixing these issues one by one is also a waste of time in my opinion. You'd need to completely review the code and architecture to get anywhere near real security, and I don't see that happening soon for Blender, or similar CG software for that matter.

Realistically, Blender is not well protected against these kinds of attacks, and the same is true for other CG software (often you can run arbitrary embedded scripts on file load, which Blender at least prevents). Anyone capable of exploiting these reported vulnerabilities can find 10 more in Blender and its library dependencies. As far as I'm concerned, opening a file with Blender should be considered like opening a file with the Python interpreter, you have the trust to the source it is coming from. CG artists might not be aware of this and that's a problem, but fixing these issues one by one is also a waste of time in my opinion. You'd need to completely review the code and architecture to get anywhere near real security, and I don't see that happening soon for Blender, or similar CG software for that matter.
Member

Cisco wrote this yesterday:
http://blog.talosintelligence.com/2018/01/unpatched-blender-vulns.html

For the record - a day after Brecht's reply I talked to a Cisco engineer who offered to help us with it.
Brecht is speaking here on his own terms, as one of the core team members but it's not an official Blender Foundation statement that we don't take these vulnerabilities seriously. There are just no simple or easy answers.

Cisco wrote this yesterday: http://blog.talosintelligence.com/2018/01/unpatched-blender-vulns.html For the record - a day after Brecht's reply I talked to a Cisco engineer who offered to help us with it. Brecht is speaking here on his own terms, as one of the core team members but it's not an official Blender Foundation statement that we don't take these vulnerabilities seriously. There are just no simple or easy answers.
Member

@yyounan now that they are published and I wouldn't mind taking a quick peek (I'm not with the BF, had no access before). Most of the reports mention

Included with this advisory is a generator for the vulnerability. 

but I don't think they made it onto the website? anything you can do there?

@yyounan now that they are published and I wouldn't mind taking a quick peek (I'm not with the BF, had no access before). Most of the reports mention ``` Included with this advisory is a generator for the vulnerability. ``` but I don't think they made it onto the website? anything you can do there?

Right, I am not speaking for the Blender Foundation. Nor am I saying vulnerabilities should not be taken seriously, but rather that if anyone is serious about making loading arbitrary .blend files in Blender secure, fixing these issues reported by TALOS will not get us much closer to that. Users should understand that loading untrusted scene files in Blender and other CG software is not currently secure, and not get the false impression that software developers addressing the occasional reported issue means it will be secure.

For background on security and arbitrary code execution in CG software in general, see here:
https://www.security-assessment.com/files/documents/presentations/Hacking-Hollywood_Nick-Freeman_Ruxcon2011.pdf

Right, I am not speaking for the Blender Foundation. Nor am I saying vulnerabilities should not be taken seriously, but rather that if anyone is serious about making loading arbitrary .blend files in Blender secure, fixing these issues reported by TALOS will not get us much closer to that. Users should understand that loading untrusted scene files in Blender and other CG software is not currently secure, and not get the false impression that software developers addressing the occasional reported issue means it will be secure. For background on security and arbitrary code execution in CG software in general, see here: https://www.security-assessment.com/files/documents/presentations/Hacking-Hollywood_Nick-Freeman_Ruxcon2011.pdf

(Also not speaking for the Blender Foundation)

Thinking what could be the solution could be here, since currently a blend file is basically a memory dump which has few validation checks on load.

Suggestion:

  • Keep blend file loading fast for the common case (When "Trusted Source" is enabled).
  • When "Trusted Source" is disabled, run extra validation code on the blend file... checking everything from.
    • Edge/loop/polygon vertex ranges (that all indices are in valid ranges, unless they're bounds checked at run-time)
    • That allocated memory is the expected size (Mesh.mvert length is consistent with Mesh.totvert for eg).
    • That strings are null terminated (with a few exceptions where it's not needed).
  • Recovering gracefully from these errors doesn't have to be a priority - any data with an error can be removed for eg, Loading the file could abort... or worst case Blender could exit (although I'd rather avoid that).

It would not be so hard to setup a fuzzer that uses existing Blend files in our test repository, injecting errors, which runs as part of a test, using tools such as ASAN / Valgrind to detect errors.

One area I think might end up being difficult to solve well is making sure partially loaded files don't have errors with invalid data - making sure versioning code can optionally perform these extra checks too.

Nevertheless - validating a blend file once it's loaded could be a first step, other issues could be handled on a case-by-case basis.


  • Note that I generally agree with Brecht's comments, just suggesting how this might be handled.
  • This could be investigated in a branch, it won't touch too many files for the fuzzing-tests + post-load-validation.
  • Once in a while we get bug reports containing corrupt files, so there is some use for this as a way to recover data. OTOH there is a limit to what we can reasonably recover depending on the kind of corruption.
  • On the down-side it's possible this ends up being a fools errand (where we can't even get close to resolving 100% of the the errors exposed by fuzzing - spending time trying to fix hypothetical errors which could be better spent investigating bugs users are actually experiencing)
*(Also not speaking for the Blender Foundation)* Thinking what could be the solution could be here, since currently a blend file is basically a memory dump which has few validation checks on load. Suggestion: - Keep blend file loading fast for the common case (When "Trusted Source" is enabled). - When "Trusted Source" is disabled, run extra validation code on the blend file... checking everything from. - Edge/loop/polygon vertex ranges *(that all indices are in valid ranges, unless they're bounds checked at run-time)* - That allocated memory is the expected size (Mesh.mvert length is consistent with Mesh.totvert for eg). - That strings are null terminated (with a few exceptions where it's not needed). - Recovering gracefully from these errors doesn't have to be a priority - any data with an error can be removed for eg, Loading the file could abort... or worst case Blender could exit *(although I'd rather avoid that)*. It would not be so hard to setup a fuzzer that uses existing Blend files in our test repository, injecting errors, which runs as part of a test, using tools such as ASAN / Valgrind to detect errors. One area I think might end up being difficult to solve well is making sure partially loaded files don't have errors with invalid data - making sure versioning code can optionally perform these extra checks too. Nevertheless - validating a blend file once it's loaded could be a first step, other issues could be handled on a case-by-case basis. ---- - Note that I generally agree with Brecht's comments, just suggesting how this might be handled. - This could be investigated in a branch, it won't touch too many files for the fuzzing-tests + post-load-validation. - Once in a while we get bug reports containing corrupt files, so there is some use for this as a way to recover data. OTOH there is a limit to what we can reasonably recover depending on the kind of corruption. - On the down-side it's possible this ends up being a fools errand *(where we can't even get close to resolving 100% of the the errors exposed by fuzzing - spending time trying to fix hypothetical errors which could be better spent investigating bugs users are actually experiencing)*

I agree it would be good to validate .blend file contents, in the generic ways that you mention it probably wouldn't add too much code complexity? The tricky part is the more complex data relations, mesh being the primary one for which we already have a validation function, but there's other ones which could be corrupted too (particles, curves, node trees, ..).

There's vulnerabilities after .blend file loading as well, if you can create a modifier setup that crashes for example, or can make a memory allocation fail in code that doesn't check if malloc returns NULL, ... .

I think the security issues in image file loading are probably the important thing to fix first, since those are generally expected to be safe to load. Maybe updating to the latest library versions for all our dependencies. But note that for example even the latest OpenEXR release has issues too:
https://github.com/openexr/openexr/issues/232

I agree it would be good to validate .blend file contents, in the generic ways that you mention it probably wouldn't add too much code complexity? The tricky part is the more complex data relations, mesh being the primary one for which we already have a validation function, but there's other ones which could be corrupted too (particles, curves, node trees, ..). There's vulnerabilities after .blend file loading as well, if you can create a modifier setup that crashes for example, or can make a memory allocation fail in code that doesn't check if malloc returns `NULL`, ... . I think the security issues in image file loading are probably the important thing to fix first, since those are generally expected to be safe to load. Maybe updating to the latest library versions for all our dependencies. But note that for example even the latest OpenEXR release has issues too: https://github.com/openexr/openexr/issues/232

Right, making data which doesn't crash but is logically invalid is a problem, although I'm not sure these are security issues.

  • Linked list that's circular.
  • Null pointers that are expected to be valid (Object.data for Meshes for eg).
  • Modifiers or configurations that allocate more memory than is available.

AFAIK these could cause infinite loops or crash on NULL pointer access *. but aren't bugs that expose Blender to attacks.


* If it's indexed it could be used to exploit I'd imagine.

Right, making data which doesn't crash but is logically invalid is a problem, although I'm not sure these are security issues. - Linked list that's circular. - Null pointers that are expected to be valid (Object.data for Meshes for eg). - Modifiers or configurations that allocate more memory than is available. AFAIK these could cause infinite loops or crash on NULL pointer access *. but aren't bugs that expose Blender to attacks. ---- \* If it's indexed it could be used to exploit I'd imagine.

Right, what I mean is that invalid data that slips through .blend file loading could cause crashes later on, because the code generally assumes it to be valid and what happens when it isn't is unpredictable. And also technically valid data can cause problems.

For example an attacker could stuff executable code in mesh vertex coordinates (which can be arbitrary bits), and as a result all mesh processing code would need to be checked for buffer overflows, in modifiers, rendering, etc. I'm not sure what kind of severity such crashes would be assigned, but it's not obvious to me that they would be harder to exploit than the multires issue described in #52924#462765.

Right, what I mean is that invalid data that slips through .blend file loading could cause crashes later on, because the code generally assumes it to be valid and what happens when it isn't is unpredictable. And also technically valid data can cause problems. For example an attacker could stuff executable code in mesh vertex coordinates (which can be arbitrary bits), and as a result all mesh processing code would need to be checked for buffer overflows, in modifiers, rendering, etc. I'm not sure what kind of severity such crashes would be assigned, but it's not obvious to me that they would be harder to exploit than the multires issue described in #52924#462765.

And to be a bit more explicit: if I had to guess, then I estimate that seriously securing Blender against these types of attacks would take at least 4 developers working full time for 2 years. Which is not an argument against addressing vulnerabilities, but just to give an idea of the cost.

And to be a bit more explicit: if I had to guess, then I estimate that seriously securing Blender against these types of attacks would take at least 4 developers working full time for 2 years. Which is not an argument against addressing vulnerabilities, but just to give an idea of the cost.
Member

Added subscriber: @blend-it

Added subscriber: @blend-it
Member

I thought that the main culprit was that we allow memory size be calculated without checks for integer overflows.
A way to fix is it to use a malloc function that accepts two args (how calloc() does it) and to make an integer mult function with boundary checks.

And: get a GSoC student to help with it :)

I thought that the main culprit was that we allow memory size be calculated without checks for integer overflows. A way to fix is it to use a malloc function that accepts two args (how calloc() does it) and to make an integer mult function with boundary checks. And: get a GSoC student to help with it :)

The reported vulnerabilities indeed are all based on cases where there is some overflow in computing the size for memory allocation, and which can be triggered by changing an integer in the file.

The reported vulnerabilities indeed are all based on cases where there is some overflow in computing the size for memory allocation, and which can be triggered by changing an integer in the file.

While it's fine to address issues raised in these reports - the errors found were using an automated tool, in some ways it's not so different from this kinds of reports (#18799 #39858) just more detailed.

Anyone looking could probably find as many buffer overrun bugs in blend file loading code (unterminated strings in the blend file for eg).
There are quite a few places that could be used for intentional stack smashing.

While all kinds of security risks should be taken seriously, it seems odd only to bother fixing issues with CVE's, when other kinds of errors aren't hard to spot in the code.

While it's fine to address issues raised in these reports - the errors found were using an automated tool, in some ways it's not so different from this kinds of reports (#18799 #39858) just more detailed. Anyone looking could probably find as many buffer overrun bugs in blend file loading code (unterminated strings in the blend file for eg). There are quite a few places that could be used for intentional stack smashing. - [`BLI_make_file_string` ](https://developer.blender.org/diffusion/B/browse/master/source/blender/blenlib/intern/path_util.c;e428ea3e0055dd95445694a72ff5c6b491a46ec7$1310-1325) - [`add_name` (makesdna.c) ](https://developer.blender.org/diffusion/B/browse/master/source/blender/makesdna/intern/makesdna.c;e428ea3e0055dd95445694a72ff5c6b491a46ec7$306) - [`rna_ParticleTarget_name_get` ](https://developer.blender.org/diffusion/B/browse/master/source/blender/makesrna/intern/rna_particle.c;e428ea3e0055dd95445694a72ff5c6b491a46ec7$1021) While all kinds of security risks should be taken seriously, it seems odd only to bother fixing issues with CVE's, when other kinds of errors aren't hard to spot in the code.

Indeed, that's the point I was trying to make in #52924#469725. In my opinion there is nothing we can do to fundamentally improve .blend file loading security against these types of (difficult and somewhat unlikely) attacks in the short term. Ironically, if we had worse security and allowed executing embedded scripts on load by default as a feature, like other software, then these wouldn't really be vulnerabilities.

However there's some practical issues like FreeBSD giving build errors when a package version has open CVEs, and just the fact that it looks bad. For image files at least we can consider any known issues important to fix. So we might as well get the CVEs fixed for 2.79a I think.

Indeed, that's the point I was trying to make in #52924#469725. In my opinion there is nothing we can do to fundamentally improve .blend file loading security against these types of (difficult and somewhat unlikely) attacks in the short term. Ironically, if we had worse security and allowed executing embedded scripts on load by default as a feature, like other software, then these wouldn't really be vulnerabilities. However there's some practical issues like FreeBSD giving build errors when a package version has open CVEs, and just the fact that it looks bad. For image files at least we can consider any known issues important to fix. So we might as well get the CVEs fixed for 2.79a I think.

@brecht the time you posted, I didn't realize these were found with an automatic detection method.

Some additional comments:

  • The buffer overruns I listed above are in fact quite crappy code and could lead to crashes (in practice they it's unlikely), good to solve still - but not priority.
  • We use an old OpenJPEG 1.5.2 (current version is 2.3). [See CVE's ]] I've upgraded the library in [ https:*developer.blender.org/diffusion/B/browse/temp-openjpeg23/ | temp-openjpeg23 branch. Last time we looked into using the new library there was a conflict with OpenImageIO. Not sure if it's resolved now.
@brecht the time you posted, I didn't realize these were found with an automatic detection method. Some additional comments: - The buffer overruns I listed above are in fact quite crappy code and *could* lead to crashes (in practice they it's unlikely), good to solve still - but not priority. - We use an old OpenJPEG 1.5.2 (current version is 2.3). [See CVE's ]] I've upgraded the library in [[ https:*developer.blender.org/diffusion/B/browse/temp-openjpeg23/ | `temp-openjpeg23` ](https:*www.cvedetails.com/vendor/12064/Openjpeg.html) branch. Last time we looked into using the new library there was a conflict with OpenImageIO. Not sure if it's resolved now.
Member

oiio will build against openjpeg 2.x, however when updating the openjpeg in /extern we'll also have to update (atleast for windows) the oiio/openjpeg libs in svn so this upgrade will have to be coordinated with the platform teams.

oiio will build against openjpeg 2.x, however when updating the openjpeg in /extern we'll also have to update (atleast for windows) the oiio/openjpeg libs in svn so this upgrade will have to be coordinated with the platform teams.

The image related CVEs reported here are now fixed.

Our libpng, libjpeg and openexr versions also have open CVEs, and possibly other libraries. I've created D3005 for these image library updates, but I doubt we can get this done for 2.79a.

The image related CVEs reported here are now fixed. Our libpng, libjpeg and openexr versions also have open CVEs, and possibly other libraries. I've created [D3005](https://archive.blender.org/developer/D3005) for these image library updates, but I doubt we can get this done for 2.79a.

We now have fixes for the other vulnerabilities in .blend file loading ass well.

While the specific overflow issue may be fixed, loading the repro .blend files may still crash because they are incomplete and corrupt. The way they crash may be impossible to exploit, but this is difficult to prove. As already mentioned, making loading of malicious .blend files safe in general would be a huge project, so that was never going to happen in the short term.

We now have fixes for the other vulnerabilities in .blend file loading ass well. While the specific overflow issue may be fixed, loading the repro .blend files may still crash because they are incomplete and corrupt. The way they crash may be impossible to exploit, but this is difficult to prove. As already mentioned, making loading of malicious .blend files safe in general would be a huge project, so that was never going to happen in the short term.

Added subscriber: @antoniov

Added subscriber: @antoniov

@brecht What I need to look for/change in greasepencil-object branch to apply these fixes?

As this branch was not part of your update patch, I would like to apply the fix before merge to 2.8 and avoid add new vulnerabilities when the merge will be done.

@brecht What I need to look for/change in greasepencil-object branch to apply these fixes? As this branch was not part of your update patch, I would like to apply the fix before merge to 2.8 and avoid add new vulnerabilities when the merge will be done.

Merge with blender2.8 as you were already doing, and use MEM_malloc_arrayN() functions in new code. But note that we did not use these functions in all of Blender yet, just a few parts related to the reports. So even if the grease pencil code did not use them, that wouldn't make much difference.

Merge with `blender2.8` as you were already doing, and use `MEM_malloc_arrayN()` functions in new code. But note that we did not use these functions in all of Blender yet, just a few parts related to the reports. So even if the grease pencil code did not use them, that wouldn't make much difference.

Added subscriber: @oxben

Added subscriber: @oxben

Was it done on purpose that the vulnerability fixes have been pushed to the branch blender-v2.79-release and not blender-v2.79a-release?

Was it done on purpose that the vulnerability fixes have been pushed to the branch blender-**v2.79**-release and not blender-**v2.79a**-release?

Added subscriber: @MarcClintDion

Added subscriber: @MarcClintDion

This comment was removed by @MarcClintDion

*This comment was removed by @MarcClintDion*

In #52924#479972, @oxben wrote:
Was it done on purpose that the vulnerability fixes have been pushed to the branch blender-v2.79-release and not blender-v2.79a-release?

Thanks for catching that, fixed now.

> In #52924#479972, @oxben wrote: > Was it done on purpose that the vulnerability fixes have been pushed to the branch blender-**v2.79**-release and not blender-**v2.79a**-release? Thanks for catching that, fixed now.

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'

All the known security issues has been fixed in Blender code, and are part of 2.79a release (which is currently at RC state).

All the known security issues has been fixed in Blender code, and are part of 2.79a release (which is currently at RC state).
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
11 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#52924
No description provided.