On Thu, Nov 7, 2019 at 2:00 PM Alexander Potapenko <glider@xxxxxxxxxx> wrote: > > On Tue, Nov 5, 2019 at 4:02 PM Alexander Potapenko <glider@xxxxxxxxxx> wrote: > > > > On Wed, Oct 30, 2019 at 3:38 PM Christoph Hellwig <hch@xxxxxx> wrote: > > > > > > On Wed, Oct 30, 2019 at 03:22:34PM +0100, glider@xxxxxxxxxx wrote: > > > > When data is copied to memory from a device KMSAN should treat it as > > > > initialized. In most cases it's enough to just unpoison the buffer that > > > > is known to come from a device. > > > > In the case with __do_page_cache_readahead() and bio_copy_user_iov() we > > > > have to mark the whole pages as ignored by KMSAN, as it's not obvious > > > > where these pages are read again. > > > > > > A lot of this looks pretty strange. Why don't you instrument > > > the dma_map / dma_sync infrastucture? That should avoid most of the > > > driver hooks. > > > > That's the exact reason I'm sending these patches: I simply don't know > > the kernel code good enough. > > May I ask you for some pointers? > > My goal is to mark data copied from the device as initialized (by > > calling kmsan_unpoison_shadow(ptr, size)), and, if possible, check > > data that's about to be copied to device (by calling > > kmsan_check_memory(ptr, size)). > > My understanding is that: > > 1. calls to dma_map_* and dma_sync_* with direction=DMA_FROM_DEVICE > > denote that the corresponding kernel buffer can be marked as > > initialized > > 2. calls to dma_unmap_* and dma_sync_* with direction=DMA_TO_DEVICE > > denote that the buffer will be copied to device (and must be checked > > for being initialized) > > 3. I need some translation table to find out the virtual address for > > a given dma_addr_t > > Does this sound reasonable? > Initializing memory in dma_map_ still leaves out the reports as the one below. > There seems to be a DMA access somewhere in blk_execute_rq(), but I > fail to see why it's not covered. > > ============================================= > BUG: KMSAN: uninit-value in[< none >] > sr_check_events+0x1091/0x1190 drivers/scsi/sr.c:246 > CPU: 0 PID: 5 Comm: kworker/0:0 Not tainted 5.4.0-rc5+ #3266 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 > Workqueue: events_freezable_power_ disk_events_workfn > Call Trace: > [< inline >] __dump_stack lib/dump_stack.c:77 > [< none >] dump_stack+0x196/0x1f0 lib/dump_stack.c:113 > [< none >] kmsan_report+0x127/0x220 mm/kmsan/kmsan_report.c:108 > [< none >] __msan_warning+0x73/0xe0 mm/kmsan/kmsan_instr.c:245 > [< inline >] sr_get_events drivers/scsi/sr.c:213 > [< none >] sr_check_events+0x1091/0x1190 drivers/scsi/sr.c:246 > [< inline >] cdrom_update_events drivers/cdrom/cdrom.c:1476 > [< none >] cdrom_check_events+0xc3/0x260 drivers/cdrom/cdrom.c:1486 > [< none >] sr_block_check_events+0x3c4/0x670 drivers/scsi/sr.c:614 > [< none >] disk_check_events+0x154/0x8b0 block/genhd.c:1855 > [< none >] disk_events_workfn+0x47/0x50 block/genhd.c:1841 > [< none >] process_one_work+0x1556/0x1ef0 kernel/workqueue.c:2269 > ... > Uninit was stored to memory at: > [< inline >] kmsan_save_stack_with_flags mm/kmsan/kmsan.c:151 > [< none >] kmsan_internal_chain_origin+0xa3/0x160 > mm/kmsan/kmsan.c:319 > [< none >] kmsan_memcpy_memmove_metadata+0x271/0x2e0 > mm/kmsan/kmsan.c:254 > [< none >] kmsan_memcpy_metadata+0xb/0x10 mm/kmsan/kmsan.c:274 > [< none >] __msan_memcpy+0x55/0x70 mm/kmsan/kmsan_instr.c:129 > [< none >] bio_copy_kern_endio_read+0x467/0x990 block/bio.c:1543 > [< none >] bio_endio+0xa36/0xbb0 block/bio.c:1850 > [< inline >] req_bio_endio block/blk-core.c:242 > [< none >] blk_update_request+0xd3c/0x20a0 block/blk-core.c:1462 > [< none >] scsi_end_request+0x10b/0xeb0 drivers/scsi/scsi_lib.c:579 > [< none >] scsi_io_completion+0x279/0x2660 > drivers/scsi/scsi_lib.c:963 > [< none >] scsi_finish_command+0x6f9/0x720 drivers/scsi/scsi.c:228 > [< none >] scsi_softirq_done+0x772/0x980 drivers/scsi/scsi_lib.c:1477 > [< none >] blk_done_softirq+0x300/0x4f0 block/blk-softirq.c:37 > [< none >] __do_softirq+0x311/0x83d kernel/softirq.c:293 > ... > Uninit was created at: > [< none >] kmsan_save_stack_with_flags+0x3f/0x90 mm/kmsan/kmsan.c:151 > [< inline >] kmsan_internal_alloc_meta_for_pages > mm/kmsan/kmsan_shadow.c:362 > [< none >] kmsan_alloc_page+0x14e/0x360 mm/kmsan/kmsan_shadow.c:391 > [< none >] __alloc_pages_nodemask+0x594e/0x6050 mm/page_alloc.c:4796 > [< none >] alloc_pages_current+0x682/0x990 mm/mempolicy.c:2188 > [< inline >] alloc_pages ./include/linux/gfp.h:511 > [< none >] bio_copy_kern+0x4c5/0xed0 block/bio.c:1590 > [< none >] blk_rq_map_kern+0x458/0x7e0 block/blk-map.c:237 > [< none >] __scsi_execute+0x2cf/0xaf0 drivers/scsi/scsi_lib.c:265 > [< inline >] scsi_execute_req ./include/scsi/scsi_device.h:451 > [< inline >] sr_get_events drivers/scsi/sr.c:207 > [< none >] sr_check_events+0x2ff/0x1190 drivers/scsi/sr.c:246 > [< inline >] cdrom_update_events drivers/cdrom/cdrom.c:1476 > [< none >] cdrom_check_events+0xc3/0x260 drivers/cdrom/cdrom.c:1486 > [< none >] sr_block_check_events+0x3c4/0x670 drivers/scsi/sr.c:614 > [< none >] disk_check_events+0x154/0x8b0 block/genhd.c:1855 > [< none >] disk_events_workfn+0x47/0x50 block/genhd.c:1841 > ============================================= Turned out these reports were coming from reads from iomapped memory. Unpoisoning those (in lib/iomap.c) in addition to DMA reads will probably eliminate the need of ad-hoc annotations in device drivers. > > I still don't understand how to handle DMA_BIDIRECTIONAL. Will it be > > sane to assume that at each dma_{map,sync,unmap}_* call must always > > check the memory range and then unpoison it? > > > > Thanks in advance > > > > -- > > Alexander Potapenko > > Software Engineer > > > > Google Germany GmbH > > Erika-Mann-Straße, 33 > > 80636 München > > > > Geschäftsführer: Paul Manicle, Halimah DeLaine Prado > > Registergericht und -nummer: Hamburg, HRB 86891 > > Sitz der Gesellschaft: Hamburg > > > > -- > Alexander Potapenko > Software Engineer > > Google Germany GmbH > Erika-Mann-Straße, 33 > 80636 München > > Geschäftsführer: Paul Manicle, Halimah DeLaine Prado > Registergericht und -nummer: Hamburg, HRB 86891 > Sitz der Gesellschaft: Hamburg -- Alexander Potapenko Software Engineer Google Germany GmbH Erika-Mann-Straße, 33 80636 München Geschäftsführer: Paul Manicle, Halimah DeLaine Prado Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg