History

mm: kmsan: handle alloc failures in kmsan_ioremap_page_range()

Similarly to kmsan_vmap_pages_range_noflush(), kmsan_ioremap_page_range() must also properly handle allocation/mapping failures. In the case of such, it must clean up the already created metadata mappings and return an error code, so that the error can be propagated to ioremap_page_range(). Without doing so, KMSAN may silently fail to bring the metadata for the page range into a consistent state, which will result in user-visible crashes when trying to access them.

Alexander Potapenko committed 3 years ago

Commit fdea03e1 parent 47ebd033 files · +59 −19Browse files

Showing the changes to include (1 of 3 files). Show all

Unified · Split

include/linux/kmsan.h+10−9
@@ -160,11 +160,12 @@ void kmsan_vunmap_range_noflush(unsigned long start, unsigned long end); · 159 unmodified lines
160 * @page_shift: page_shift argument passed to vmap_range_noflush().160 * @page_shift: page_shift argument passed to vmap_range_noflush().
161 *161 *
162 * KMSAN creates new metadata pages for the physical pages mapped into the162 * KMSAN creates new metadata pages for the physical pages mapped into the
163 * virtual memory.163 * virtual memory. Returns 0 on success, callers must check for non-zero return
164 * value.
164 */165 */
165void kmsan_ioremap_page_range(unsigned long addr, unsigned long end,166int kmsan_ioremap_page_range(unsigned long addr, unsigned long end,
166 phys_addr_t phys_addr, pgprot_t prot,167 phys_addr_t phys_addr, pgprot_t prot,
167 unsigned int page_shift);168 unsigned int page_shift);
168 169
169/**170/**
170 * kmsan_iounmap_page_range() - Notify KMSAN about a iounmap_page_range() call.171 * kmsan_iounmap_page_range() - Notify KMSAN about a iounmap_page_range() call.
@@ -296,12 +297,12 @@ static inline void kmsan_vunmap_range_noflush(unsigned long start, · 125 unmodified lines
296{297{
297}298}
298 299
299static inline void kmsan_ioremap_page_range(unsigned long start,300static inline int kmsan_ioremap_page_range(unsigned long start,
300 unsigned long end,301 unsigned long end,
301 phys_addr_t phys_addr,302 phys_addr_t phys_addr, pgprot_t prot,
302 pgprot_t prot,303 unsigned int page_shift)
303 unsigned int page_shift)
304{304{
305 return 0;
305}306}
306 307
307static inline void kmsan_iounmap_page_range(unsigned long start,308static inline void kmsan_iounmap_page_range(unsigned long start,