Messages in this thread | | | From | Andrey Konovalov <> | Date | Thu, 14 Feb 2019 01:27:09 +0100 | Subject | Re: [PATCH] kasan, slub: fix more conflicts with CONFIG_SLAB_FREELIST_HARDENED |
| |
On Thu, Feb 14, 2019 at 1:25 AM Andrey Konovalov <andreyknvl@google.com> wrote: > > When CONFIG_KASAN_SW_TAGS is enabled, ptr_addr might be tagged. > Normally, this doesn't cause any issues, as both set_freepointer() > and get_freepointer() are called with a pointer with the same tag. > However, there are some issues with CONFIG_SLUB_DEBUG code. For > example, when __free_slub() iterates over objects in a cache, it > passes untagged pointers to check_object(). check_object() in turns > calls get_freepointer() with an untagged pointer, which causes the > freepointer to be restored incorrectly. > > Add kasan_reset_tag to freelist_ptr(). Also add a detailed comment. > > Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Reported-by: Qian Cai <cai@lca.pw>
> --- > mm/slub.c | 13 ++++++++++++- > 1 file changed, 12 insertions(+), 1 deletion(-) > > diff --git a/mm/slub.c b/mm/slub.c > index 80da3a40b74d..c80e6699357c 100644 > --- a/mm/slub.c > +++ b/mm/slub.c > @@ -249,7 +249,18 @@ static inline void *freelist_ptr(const struct kmem_cache *s, void *ptr, > unsigned long ptr_addr) > { > #ifdef CONFIG_SLAB_FREELIST_HARDENED > - return (void *)((unsigned long)ptr ^ s->random ^ ptr_addr); > + /* > + * When CONFIG_KASAN_SW_TAGS is enabled, ptr_addr might be tagged. > + * Normally, this doesn't cause any issues, as both set_freepointer() > + * and get_freepointer() are called with a pointer with the same tag. > + * However, there are some issues with CONFIG_SLUB_DEBUG code. For > + * example, when __free_slub() iterates over objects in a cache, it > + * passes untagged pointers to check_object(). check_object() in turns > + * calls get_freepointer() with an untagged pointer, which causes the > + * freepointer to be restored incorrectly. > + */ > + return (void *)((unsigned long)ptr ^ s->random ^ > + (unsigned long)kasan_reset_tag((void *)ptr_addr)); > #else > return ptr; > #endif > -- > 2.20.1.791.gb4d0f1c61a-goog >
| |