Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/vboxvideo: Replace fake VLA at end of vbva_mouse_pointer_shape with real VLA

Replace the fake VLA at end of the vbva_mouse_pointer_shape shape with
a real VLA to fix a "memcpy: detected field-spanning write error" warning:

[ 13.319813] memcpy: detected field-spanning write (size 16896) of single field "p->data" at drivers/gpu/drm/vboxvideo/hgsmi_base.c:154 (size 4)
[ 13.319841] WARNING: CPU: 0 PID: 1105 at drivers/gpu/drm/vboxvideo/hgsmi_base.c:154 hgsmi_update_pointer_shape+0x192/0x1c0 [vboxvideo]
[ 13.320038] Call Trace:
[ 13.320173] hgsmi_update_pointer_shape [vboxvideo]
[ 13.320184] vbox_cursor_atomic_update [vboxvideo]

Note as mentioned in the added comment it seems the original length
calculation for the allocated and send hgsmi buffer is 4 bytes too large.
Changing this is not the goal of this patch, so this behavior is kept.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240827104523.17442-1-hdegoede@redhat.com

+10 -4
+9 -1
drivers/gpu/drm/vboxvideo/hgsmi_base.c
··· 139 139 flags |= VBOX_MOUSE_POINTER_VISIBLE; 140 140 } 141 141 142 - p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA, 142 + /* 143 + * The 4 extra bytes come from switching struct vbva_mouse_pointer_shape 144 + * from having a 4 bytes fixed array at the end to using a proper VLA 145 + * at the end. These 4 extra bytes were not subtracted from sizeof(*p) 146 + * before the switch to the VLA, so this way the behavior is unchanged. 147 + * Chances are these 4 extra bytes are not necessary but they are kept 148 + * to avoid regressions. 149 + */ 150 + p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len + 4, HGSMI_CH_VBVA, 143 151 VBVA_MOUSE_POINTER_SHAPE); 144 152 if (!p) 145 153 return -ENOMEM;
+1 -3
drivers/gpu/drm/vboxvideo/vboxvideo.h
··· 351 351 * Bytes in the gap between the AND and the XOR mask are undefined. 352 352 * XOR mask scanlines have no gap between them and size of XOR mask is: 353 353 * xor_len = width * 4 * height. 354 - * 355 - * Preallocate 4 bytes for accessing actual data as p->data. 356 354 */ 357 - u8 data[4]; 355 + u8 data[]; 358 356 } __packed; 359 357 360 358 /* pointer is visible */