From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5FEBC432C3 for ; Tue, 19 Nov 2019 05:23:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9DEA02231C for ; Tue, 19 Nov 2019 05:23:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574140985; bh=FxKPO7jAChxQpNp61sriPsywXO1Z/3Nf73A8Tln1LT4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=ERUC/j/1ionwW48zr+/UILOHPQkT95Ze4U7Sy05biqB+Su+spyUKMsgN5Lhv6iaoV BjWy3sA64FgPPSwOfuKFzANHz5kfOQxgORnSjPmHLDIaP5299LCTHr35k96kAQn7rf TetipbcuHgxBOArmF2LgkST3X0ye24f4g9tbBnYA= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727909AbfKSFXE (ORCPT ); Tue, 19 Nov 2019 00:23:04 -0500 Received: from mail.kernel.org ([198.145.29.99]:38494 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726905AbfKSFXC (ORCPT ); Tue, 19 Nov 2019 00:23:02 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id ABD0222350; Tue, 19 Nov 2019 05:23:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574140981; bh=FxKPO7jAChxQpNp61sriPsywXO1Z/3Nf73A8Tln1LT4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=zmNSN6CHrEAOwhSHSQavCOJXAtJOZVQ19qkesBGqgBc//J1zVJgLyLV6vrnHlrGgY 6efvw9s/oJunn2ARQaPtK4MTl+ID4v4FL3f2G1wvPLZeH3y8X20SmM/5fzaHgy/l2C nhMBkz4Q3uETQMprYMX2JB1YAPQ2h9oslCtfg+fY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Laura Abbott , Thibaut Sautereau , David Rientjes , Alexander Potapenko , Kees Cook , "David S. Miller" , Vlastimil Babka , clipos@ssi.gouv.fr, Christoph Lameter , Pekka Enberg , Joonsoo Kim , Andrew Morton , Linus Torvalds Subject: [PATCH 5.3 45/48] mm: slub: really fix slab walking for init_on_free Date: Tue, 19 Nov 2019 06:20:05 +0100 Message-Id: <20191119051028.131345484@linuxfoundation.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191119050946.745015350@linuxfoundation.org> References: <20191119050946.745015350@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Laura Abbott commit aea4df4c53f754cc229edde6c5465e481311cc49 upstream. Commit 1b7e816fc80e ("mm: slub: Fix slab walking for init_on_free") fixed one problem with the slab walking but missed a key detail: When walking the list, the head and tail pointers need to be updated since we end up reversing the list as a result. Without doing this, bulk free is broken. One way this is exposed is a NULL pointer with slub_debug=F: ============================================================================= BUG skbuff_head_cache (Tainted: G T): Object already free ----------------------------------------------------------------------------- INFO: Slab 0x000000000d2d2f8f objects=16 used=3 fp=0x0000000064309071 flags=0x3fff00000000201 BUG: kernel NULL pointer dereference, address: 0000000000000000 Oops: 0000 [#1] PREEMPT SMP PTI RIP: 0010:print_trailer+0x70/0x1d5 Call Trace: free_debug_processing.cold.37+0xc9/0x149 __slab_free+0x22a/0x3d0 kmem_cache_free_bulk+0x415/0x420 __kfree_skb_flush+0x30/0x40 net_rx_action+0x2dd/0x480 __do_softirq+0xf0/0x246 irq_exit+0x93/0xb0 do_IRQ+0xa0/0x110 common_interrupt+0xf/0xf Given we're now almost identical to the existing debugging code which correctly walks the list, combine with that. Link: https://lkml.kernel.org/r/20191104170303.GA50361@gandi.net Link: http://lkml.kernel.org/r/20191106222208.26815-1-labbott@redhat.com Fixes: 1b7e816fc80e ("mm: slub: Fix slab walking for init_on_free") Signed-off-by: Laura Abbott Reported-by: Thibaut Sautereau Acked-by: David Rientjes Tested-by: Alexander Potapenko Acked-by: Alexander Potapenko Cc: Kees Cook Cc: "David S. Miller" Cc: Vlastimil Babka Cc: Cc: Christoph Lameter Cc: Pekka Enberg Cc: Joonsoo Kim Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/slub.c | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) --- a/mm/slub.c +++ b/mm/slub.c @@ -1432,12 +1432,15 @@ static inline bool slab_free_freelist_ho void *old_tail = *tail ? *tail : *head; int rsize; - if (slab_want_init_on_free(s)) { - void *p = NULL; + /* Head and tail of the reconstructed freelist */ + *head = NULL; + *tail = NULL; + + do { + object = next; + next = get_freepointer(s, object); - do { - object = next; - next = get_freepointer(s, object); + if (slab_want_init_on_free(s)) { /* * Clear the object and the metadata, but don't touch * the redzone. @@ -1447,29 +1450,8 @@ static inline bool slab_free_freelist_ho : 0; memset((char *)object + s->inuse, 0, s->size - s->inuse - rsize); - set_freepointer(s, object, p); - p = object; - } while (object != old_tail); - } - -/* - * Compiler cannot detect this function can be removed if slab_free_hook() - * evaluates to nothing. Thus, catch all relevant config debug options here. - */ -#if defined(CONFIG_LOCKDEP) || \ - defined(CONFIG_DEBUG_KMEMLEAK) || \ - defined(CONFIG_DEBUG_OBJECTS_FREE) || \ - defined(CONFIG_KASAN) - - next = *head; - /* Head and tail of the reconstructed freelist */ - *head = NULL; - *tail = NULL; - - do { - object = next; - next = get_freepointer(s, object); + } /* If object's reuse doesn't have to be delayed */ if (!slab_free_hook(s, object)) { /* Move object to the new freelist */ @@ -1484,9 +1466,6 @@ static inline bool slab_free_freelist_ho *tail = NULL; return *head != NULL; -#else - return true; -#endif } static void *setup_object(struct kmem_cache *s, struct page *page,