Package: libdrm2
Version: 2.4.103-1
Severity: normal
Tags: patch
X-Debbugs-Cc: davide.pr...@gmail.com

Hi,

the instruction (line 3594 of xf86drm.c file):
memcpy(device->nodes[type], node, max_node_length);

read from node over the node allocated size as you can see from valgrind
output that execute a piglit (see tha package piglit for mor info) test:

$ valgrind --num-callers=50 --exit-on-first-error=yes --keep-debuginfo=yes 
bin/arb_separate_shader_object-mix-and-match-tcs-tes

==33238== Invalid read of size 8
==33238==    at 0x5C6F6CA: ??? (in /usr/lib/x86_64-linux-gnu/libdrm.so.2.4.0)
==33238==    by 0x5C707C1: ??? (in /usr/lib/x86_64-linux-gnu/libdrm.so.2.4.0)
==33238==    by 0x5C746FE: drmGetDevice2 (in 
/usr/lib/x86_64-linux-gnu/libdrm.so.2.4.0)
==33238==    by 0x5C0D1B8: ??? (in 
/usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==33238==    by 0x5C0326E: ??? (in 
/usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==33238==    by 0x5BF1E08: ??? (in 
/usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==33238==    by 0x5BEE4ED: ??? (in 
/usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==33238==    by 0x4CEA640: ??? (in 
/usr/lib/x86_64-linux-gnu/libwaffle-1.so.0.6.1)
==33238==    by 0x49E0081: wfl_checked_display_connect (piglit-util-waffle.h:74)
==33238==    by 0x49E0081: piglit_wfl_framework_init 
(piglit_wfl_framework.c:627)
==33238==    by 0x49E055F: piglit_winsys_framework_init 
(piglit_winsys_framework.c:209)
==33238==    by 0x49E0DCA: piglit_x11_framework_create 
(piglit_x11_framework.c:229)
==33238==    by 0x49D4728: piglit_gl_test_run (piglit-framework-gl.c:221)
==33238==    by 0x10A1A1: main (mix-and-match-tcs-tes.c:48)
==33238==  Address 0x58c1960 is 1 bytes after a block of size 15 alloc'd
==33238==    at 0x483877F: malloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==33238==    by 0x5C70638: ??? (in /usr/lib/x86_64-linux-gnu/libdrm.so.2.4.0)
==33238==    by 0x5C746FE: drmGetDevice2 (in 
/usr/lib/x86_64-linux-gnu/libdrm.so.2.4.0)
==33238==    by 0x5C0D1B8: ??? (in 
/usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==33238==    by 0x5C0326E: ??? (in 
/usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==33238==    by 0x5BF1E08: ??? (in 
/usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==33238==    by 0x5BEE4ED: ??? (in 
/usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==33238==    by 0x4CEA640: ??? (in 
/usr/lib/x86_64-linux-gnu/libwaffle-1.so.0.6.1)
==33238==    by 0x49E0081: wfl_checked_display_connect (piglit-util-waffle.h:74)
==33238==    by 0x49E0081: piglit_wfl_framework_init 
(piglit_wfl_framework.c:627)
==33238==    by 0x49E055F: piglit_winsys_framework_init 
(piglit_winsys_framework.c:209)
==33238==    by 0x49E0DCA: piglit_x11_framework_create 
(piglit_x11_framework.c:229)
==33238==    by 0x49D4728: piglit_gl_test_run (piglit-framework-gl.c:221)
==33238==    by 0x10A1A1: main (mix-and-match-tcs-tes.c:48)

Afret installing the package with detached debug symbols you can see the
rows and file:
==17446== Invalid read of size 8
==17446==    at 0x5C706CA: UnknownInlinedFun (string_fortified.h:34)
==17446==    by 0x5C706CA: drmDeviceAlloc (xf86drm.c:3594)
==17446==    by 0x5C717C1: drmProcessPciDevice (xf86drm.c:3610)
==17446==    by 0x5C717C1: process_device (xf86drm.c:4012)
==17446==    by 0x5C756FE: drmGetDevice2 (xf86drm.c:4190)
==17446==    by 0x5C0E1B8: drm_get_id_path_tag_for_fd (loader.c:292)
==17446==    by 0x5C0E1B8: loader_get_user_preferred_fd (loader.c:319)
==17446==    by 0x5C0426E: dri3_create_screen (dri3_glx.c:866)
==17446==    by 0x5BF2E08: AllocAndFetchScreenConfigs (glxext.c:818)
==17446==    by 0x5BF2E08: __glXInitialize (glxext.c:949)
==17446==    by 0x5BEF4ED: GetGLXPrivScreenConfig (glxcmds.c:174)
==17446==    by 0x5BEF4ED: glXQueryExtensionsString (glxcmds.c:1307)
==17446==    by 0x4CEB640: wrapped_glXQueryExtensionsString (glx_wrappers.h:129)
==17446==    by 0x4CEB640: glx_display_set_extensions (glx_display.c:55)
==17446==    by 0x4CEB640: glx_display_connect (glx_display.c:105)
[...]
==17446==  Address 0x58c2da0 is 1 bytes after a block of size 15 alloc'd
==17446==    at 0x483877F: malloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==17446==    by 0x5C71638: process_device (xf86drm.c:3987)
==17446==    by 0x5C756FE: drmGetDevice2 (xf86drm.c:4190)
==17446==    by 0x5C0E1B8: drm_get_id_path_tag_for_fd (loader.c:292)
==17446==    by 0x5C0E1B8: loader_get_user_preferred_fd (loader.c:319)
==17446==    by 0x5C0426E: dri3_create_screen (dri3_glx.c:866)
==17446==    by 0x5BF2E08: AllocAndFetchScreenConfigs (glxext.c:818)
==17446==    by 0x5BF2E08: __glXInitialize (glxext.c:949)
==17446==    by 0x5BEF4ED: GetGLXPrivScreenConfig (glxcmds.c:174)
==17446==    by 0x5BEF4ED: glXQueryExtensionsString (glxcmds.c:1307)
==17446==    by 0x4CEB640: wrapped_glXQueryExtensionsString (glx_wrappers.h:129)
==17446==    by 0x4CEB640: glx_display_set_extensions (glx_display.c:55)
==17446==    by 0x4CEB640: glx_display_connect (glx_display.c:105)
[...]

As you can see the instruction at xf86drm.c:3987, that it is:
node = malloc(len);

allocate a space of length: len = snprintf(NULL, 0, "%s/%s", DRM_DIR_NAME, 
d_name);

but the instruction at xf86drm.c:3594, that it is:
memcpy(device->nodes[type], node, max_node_length);

try to read max_node_length elements from node, where max_node_length is
bigger than len.

To solve the problem you can replace this memcpy instruction with:
memcpy(device->nodes[type], node, max_node_length <= strlen(node)+1 ? 
max_node_length : strlen(node)+1);

I have tested it compiling the package with this modification.

I have noted also that the "node"'s allocation is not tested to see if it
is successfull, in teory "len" can be negative if you call this function
with parameters that let the instruction
len = snprintf(NULL, 0, "%s/%s", DRM_DIR_NAME, d_name);
to set the "len" variabile to the MAXINT.
Also the implicit cast cast be expicited.

I will report other errors (I will try to identify a problem with 2
Debain programs when they use some GPU instructions) let me know if you will 
prefer more
sintetic reports.

Ciao
Davide

-- System Information:
Debian Release: bullseye/sid
  APT prefers testing-debug
  APT policy: (500, 'testing-debug'), (500, 'testing'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 5.9.6-dp-20201119 (SMP w/4 CPU threads; PREEMPT)
Kernel taint flags: TAINT_UNSIGNED_MODULE
Locale: LANG=it_IT.utf8, LC_CTYPE=it_IT.utf8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages libdrm2 depends on:
ii  libc6          2.31-4
ii  libdrm-common  2.4.103-1

libdrm2 recommends no packages.

libdrm2 suggests no packages.

-- no debconf information
--- xf86drm.c.origin    2020-11-24 19:00:30.957456484 +0100
+++ xf86drm.c   2020-11-24 19:02:12.850803198 +0100
@@ -3591,8 +3591,9 @@
         ptr += max_node_length;
     }
 
-    memcpy(device->nodes[type], node, max_node_length);
-
+ /*   memcpy(device->nodes[type], node, max_node_length); */
+    memcpy(device->nodes[type], node, max_node_length <= strlen(node)+1 ? 
max_node_length : strlen(node)+1); 
+ 
     *ptrp = ptr;
 
     return device;

Reply via email to