CVE-2018-11592 (published 2018-05-31T16:29Z)

Espruino before 1.98 allows attackers to cause a denial of service (application crash) with a user crafted input file via an Out-of-bounds Read during syntax parsing in which certain height validation is missing in libs/graphics/jswrap_graphics.c.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 5.5, MEDIUM (CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-125
cwe_name: Out-of-bounds Read
description: The product reads data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/espruino/Espruino
commit_details: repo_url: https://github.com/espruino/Espruino
author: Gordon Williams
author_date: 2018-05-18 10:02:14+01:00
msg: Add height check for Graphics.createArrayBuffer(...vertical_byte:true) (fix #1421)
repository: repo_url: https://github.com/espruino/Espruino
repo_name: espruino/Espruino
description: The Espruino JavaScript interpreter - Official Repo
repo_language: C
owner: espruino
file_changes: filename: ChangeLog
change_type: ModificationType.MODIFY
diff: @@ -21,6 +21,7 @@
             Make software I2C bitrate and waveform more accurate
             Move default I2C bitrate to 100kbit/sec
             Linux: don't create a espruino.flash file if we're not writing to flash
+            Add height check for Graphics.createArrayBuffer(...vertical_byte:true) (fix #1421)
 
      1v97 : nRF52: fix NRF.on('connect',...) issue
             STM32: Fix setDeviceClockCmd error for USB.setConsole()

programming_language: Markdown
filename: jswrap_graphics.c
change_type: ModificationType.MODIFY
diff: @@ -129,8 +129,14 @@ JsVar *jswrap_graphics_createArrayBuffer(int width, int height, int bpp, JsVar *
     if (jsvGetBoolAndUnLock(jsvObjectGetChild(options, "vertical_byte", 0))) {
       if (gfx.data.bpp==1)
         gfx.data.flags = (JsGraphicsFlags)(gfx.data.flags | JSGRAPHICSFLAGS_ARRAYBUFFER_VERTICAL_BYTE);
-      else
-        jsWarn("vertical_byte only works for 1bpp ArrayBuffers\n");
+      else {
+        jsExceptionHere(JSET_ERROR, "vertical_byte only works for 1bpp ArrayBuffers\n");
+        return 0;
+      }
+      if (gfx.data.height&7) {
+        jsExceptionHere(JSET_ERROR, "height must be a multiple of 8 when using vertical_byte\n");
+        return 0;
+      }
     }
     JsVar *colorv = jsvObjectGetChild(options, "color_order", 0);
     if (colorv) {

programming_language: C++
filename: lcd_arraybuffer.c
change_type: ModificationType.MODIFY
diff: @@ -161,6 +161,7 @@ void lcdSetPixels_ArrayBuffer_flat(JsGraphics *gfx, short x, short y, short pixe
       unsigned int mask = (unsigned int)(1<<gfx->data.bpp)-1;
       unsigned int existing = (unsigned int)*ptr;
       unsigned int bitIdx = (gfx->data.flags & JSGRAPHICSFLAGS_ARRAYBUFFER_MSB) ? 8-(idx+gfx->data.bpp) : idx;
+      assert(ptr>=gfx->backendData && ptr<((char*)gfx->backendData + graphicsGetMemoryRequired(gfx)));
       *ptr = (char)((existing&~(mask<<bitIdx)) | ((col&mask)<<bitIdx));
       if (gfx->data.flags & JSGRAPHICSFLAGS_ARRAYBUFFER_VERTICAL_BYTE) {
         ptr++;

programming_language: C++