Re: [PATCH RFC v2 22/25] kmsan: unpoisoning buffers from devices etc.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
=============================================

> 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





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux