On Wed, Apr 4, 2018 at 2:39 PM, Andrey Ryabinin <aryabinin@xxxxxxxxxxxxx> wrote: >>> >>> You can save tag somewhere in page struct and make page_address() return tagged address. >>> >>> I'm not sure it might be even possible to squeeze the tag into page->flags on some configurations, >>> see include/linux/page-flags-layout.h >> >> One page can contain multiple objects with different tags, so we would >> need to save the tag for each of them. > > What do you mean? Slab page? The per-page tag is needed only for !PageSlab pages. > For slab pages we have kmalloc/kmem_cache_alloc() which already return properly tagged address. > > But the page allocator returns a pointer to struct page. One has to call page_address(page) > to use that page. Returning 'ignore-me'-tagged address from page_address() makes the whole > class of bugs invisible to KHWASAN. This is a serious downside comparing to classic KASAN which can > detect missuses of page allocator API. Yes, slab page. Here's an example: 1. do_get_write_access() allocates frozen_buffer with jbd2_alloc, which calls kmem_cache_alloc, and then saves the result to jh->b_frozen_data. 2. jbd2_journal_write_metadata_buffer() takes the value of jh_in->b_frozen_data and calls virt_to_page() (and offset_in_page()) on it. 3. jbd2_journal_write_metadata_buffer() then calls kmap_atomic(), which calls page_address(), on the resulting page address. The tag gets erased. The page belongs to slab and can contain multiple objects with different tags. >>> I don't see any possible way of khwasan_enabled being 0 here. >> >> Can't kmem_cache_alloc be called for the temporary caches that are >> used before the slab allocator and kasan are initialized? > > kasan_init() runs before allocators are initialized. > slab allocator obviously has to be initialized before it can be used. Checked the code, it seems you are right. Boot caches are created after kasan_init() is called. I will remove khwasan_enabled. Thanks!