Ubuntu 22.04: UBSAN: invalid-load in include/linux/dma-buf-map.h
notro opened this issue · comments
Noralf Trønnes commented
$ sudo dmesg
[ 0.000000] Linux version 5.15.0-27-generic (buildd@ubuntu) (gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #28-Ubuntu SMP Thu Apr 14 04:55:28 UTC 2022 (Ubuntu 5.15.0-27.28-generic 5.15.30)
[ 4.830866] usb 2-3.1: new high-speed USB device number 4 using xhci_hcd
[ 4.935546] usb 2-3.1: New USB device found, idVendor=1d50, idProduct=614d, bcdDevice= 1.00
[ 4.935553] usb 2-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 4.935556] usb 2-3.1: Product: Raspberry Pi 4 Display Gadget
[ 4.935558] usb 2-3.1: Manufacturer: Raspberry Pi
[ 4.935560] usb 2-3.1: SerialNumber: 100000003b40d6c6
[ 7.497361] [drm] Initialized gud 1.0.0 20200422 for 2-3.1:1.0 on minor 0
[ 7.573048] gud 2-3.1:1.0: [drm] fb1: guddrmfb frame buffer device
[ 9.199402] ================================================================================
[ 9.199411] UBSAN: invalid-load in /build/linux-HMZHpV/linux-5.15.0/include/linux/dma-buf-map.h:224:9
[ 9.199416] load of value 226 is not a valid value for type '_Bool'
[ 9.199420] CPU: 0 PID: 113 Comm: kworker/0:2 Not tainted 5.15.0-27-generic #28-Ubuntu
[ 9.199424] Hardware name: Hewlett-Packard HP EliteBook 820 G1/1991, BIOS L71 Ver. 01.44 04/12/2018
[ 9.199427] Workqueue: events_long gud_flush_work [gud]
[ 9.199440] Call Trace:
[ 9.199443] <TASK>
[ 9.199447] show_stack+0x52/0x58
[ 9.199456] dump_stack_lvl+0x4a/0x5f
[ 9.199464] dump_stack+0x10/0x12
[ 9.199468] ubsan_epilogue+0x9/0x45
[ 9.199473] __ubsan_handle_load_invalid_value.cold+0x44/0x49
[ 9.199478] drm_gem_fb_vmap.cold+0x10/0x3d [drm_kms_helper]
[ 9.199519] gud_prep_flush+0xaa/0x410 [gud]
[ 9.199525] ? check_preempt_curr+0x5d/0x70
[ 9.199533] ? update_load_avg+0x82/0x620
[ 9.199540] ? set_next_entity+0xb7/0x200
[ 9.199545] gud_flush_work+0x1e0/0x430 [gud]
[ 9.199551] ? psi_task_switch+0x1e7/0x220
[ 9.199557] process_one_work+0x22b/0x3d0
[ 9.199564] worker_thread+0x53/0x410
[ 9.199570] ? process_one_work+0x3d0/0x3d0
[ 9.199575] kthread+0x12a/0x150
[ 9.199579] ? set_kthread_struct+0x50/0x50
[ 9.199584] ret_from_fork+0x22/0x30
[ 9.199593] </TASK>
[ 9.199595] ================================================================================
[ 9.199598] ================================================================================
[ 9.199600] UBSAN: invalid-load in /build/linux-HMZHpV/linux-5.15.0/include/linux/dma-buf-map.h:194:9
[ 9.199604] load of value 226 is not a valid value for type '_Bool'
[ 9.199606] CPU: 0 PID: 113 Comm: kworker/0:2 Not tainted 5.15.0-27-generic #28-Ubuntu
[ 9.199610] Hardware name: Hewlett-Packard HP EliteBook 820 G1/1991, BIOS L71 Ver. 01.44 04/12/2018
[ 9.199612] Workqueue: events_long gud_flush_work [gud]
[ 9.199618] Call Trace:
[ 9.199619] <TASK>
[ 9.199621] show_stack+0x52/0x58
[ 9.199627] dump_stack_lvl+0x4a/0x5f
[ 9.199633] dump_stack+0x10/0x12
[ 9.199637] ubsan_epilogue+0x9/0x45
[ 9.199641] __ubsan_handle_load_invalid_value.cold+0x44/0x49
[ 9.199646] drm_gem_fb_vmap.cold+0x24/0x3d [drm_kms_helper]
[ 9.199675] gud_prep_flush+0xaa/0x410 [gud]
[ 9.199682] ? check_preempt_curr+0x5d/0x70
[ 9.199688] ? update_load_avg+0x82/0x620
[ 9.199693] ? update_load_avg+0x82/0x620
[ 9.199697] gud_flush_work+0x1e0/0x430 [gud]
[ 9.199702] ? psi_task_switch+0x1e7/0x220
[ 9.199706] process_one_work+0x22b/0x3d0
[ 9.199713] worker_thread+0x53/0x410
[ 9.199718] ? process_one_work+0x3d0/0x3d0
[ 9.199723] kthread+0x12a/0x150
[ 9.199728] ? set_kthread_struct+0x50/0x50
[ 9.199732] ret_from_fork+0x22/0x30
[ 9.199741] </TASK>
[ 9.199743] ================================================================================
192 static inline bool dma_buf_map_is_null(const struct dma_buf_map *map)
193 {
194 if (map->is_iomem)
195 return !map->vaddr_iomem;
196 return !map->vaddr;
197 }
222 static inline void dma_buf_map_clear(struct dma_buf_map *map)
223 {
224 if (map->is_iomem) {
225 map->vaddr_iomem = NULL;
226 map->is_iomem = false;
227 } else {
228 map->vaddr = NULL;
229 }
230 }
A likely culprit is that the map
variable is not zero initialized in gud_prep_flush() so map->is_iomem
can be any value:
static int gud_prep_flush(struct gud_device *gdrm, struct drm_framebuffer *fb,
const struct drm_format_info *format, struct drm_rect *rect,
struct gud_set_buffer_req *req)
{
struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach;
u8 compression = gdrm->compression;
struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
struct dma_buf_map map_data[DRM_FORMAT_MAX_PLANES];
void *vaddr, *buf;
size_t pitch, len;
int ret = 0;
pitch = drm_format_info_min_pitch(format, 0, drm_rect_width(rect));
len = pitch * drm_rect_height(rect);
if (len > gdrm->bulk_len)
return -E2BIG;
ret = drm_gem_fb_vmap(fb, map, map_data);
if (ret)
return ret;
I wonder why dma_buf_map_clear() has conditional clearing and not just zero the whole structure, that would solve the problem as well for all users I guess:
static inline void dma_buf_map_clear(struct dma_buf_map *map)
{
if (map->is_iomem) {
map->vaddr_iomem = NULL;
map->is_iomem = false;
} else {
map->vaddr = NULL;
}
}
Noralf Trønnes commented
Noralf Trønnes commented
Will be fixed in v6.3 (backported v5.18+): drm/gud: Fix UBSAN warning