mm: use compare-exchange operation to set KASAN page tag
Subsystems (3)
PATCH v2 1/1 mm: use compare-exchange operation to set KASAN page tag
It has been reported that the tag setting operation on newly-allocated pages can cause the page flags to be corrupted when performed concurrently with other flag updates as a result of the use of non-atomic operations. Fix the problem by using a compare-exchange loop to update the tag.
Signed-off-by Peter Collingbourne <[email protected]>
Fixes 2813b9c02962 ("kasan, mm, arm64: tag non slab memory allocated via pagealloc")
---
v2:
- use READ_ONCE()
include/linux/mm.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
include/linux/mm.h +11 -5
@@ -1531,11 +1531,17 @@ static inline u8 page_kasan_tag(const struct page *page)static inline void page_kasan_tag_set (struct page *page,u8 tag) { -if (kasan_enabled ()) { - tag ^=0xff ; - page->flags &= ~(KASAN_TAG_MASK <<KASAN_TAG_PGSHIFT ); - page->flags |= (tag &KASAN_TAG_MASK ) <<KASAN_TAG_PGSHIFT ; - } +unsigned long old_flags, flags; + +if (!kasan_enabled ()) +return ; + + tag ^=0xff ; +do { + old_flags = flags =READ_ONCE (page->flags); + flags &= ~(KASAN_TAG_MASK <<KASAN_TAG_PGSHIFT ); + flags |= (tag &KASAN_TAG_MASK ) <<KASAN_TAG_PGSHIFT ; + }while (unlikely (cmpxchg (&page->flags, old_flags, flags) != old_flags)); }static inline void page_kasan_tag_reset (struct page *page)
Signature · 1 line
2.34.1.703.g22d0c6ccf7-goog