From patchwork Tue May 10 17:43:28 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Christoph Lameter (Ampere)" X-Patchwork-Id: 95014 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 71D901007D7 for ; Wed, 11 May 2011 03:55:43 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750870Ab1EJRnd (ORCPT ); Tue, 10 May 2011 13:43:33 -0400 Received: from smtp101.prem.mail.ac4.yahoo.com ([76.13.13.40]:44432 "HELO smtp101.prem.mail.ac4.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1750775Ab1EJRnc (ORCPT ); Tue, 10 May 2011 13:43:32 -0400 Received: (qmail 5711 invoked from network); 10 May 2011 17:43:31 -0000 Received: from router.home (cl@99.30.10.212 with plain) by smtp101.prem.mail.ac4.yahoo.com with SMTP; 10 May 2011 10:43:31 -0700 PDT X-Yahoo-SMTP: _Dag8S.swBC1p4FJKLCXbs8NQzyse1SYSgnAbY0- X-YMail-OSG: RZkKbCYVM1nDSfjqUqniEOG3KlXoxLSvUGSlScQvdKqfEzu TuygEiWbyzpygJbjN3zpwUTlRiloZKjvE5KutNp5cxmjjMj5.M_YPbIsJYMe 5JVn1i0RQXmw8qm9GOcpy4_TtK8VxgFMJNGi0OiUFyZ3fYbqOcQN7_x.flOj Cy5FWlocgO3_yANwKi1ep_qZ7q0.BZJadpvPxkSHVqYARi9E5migJii8bVAz Hs.NSgsBQtQ1plACHGG7IOdsuJh.4BbFIKnzMEagShSN9uQRqZOFexqPiDtQ jKgUQBwWK3_HLcRorvLOez5wr5QaeKGg90mwkf67OL2o8Rjvl X-Yahoo-Newman-Property: ymail-3 Received: from cl (helo=localhost) by router.home with local-esmtp (Exim 4.71) (envelope-from ) id 1QJqy2-00011N-Ps; Tue, 10 May 2011 12:43:30 -0500 Date: Tue, 10 May 2011 12:43:28 -0500 (CDT) From: Christoph Lameter X-X-Sender: cl@router.home To: Eric Dumazet cc: Vegard Nossum , Pekka Enberg , casteyde.christian@free.fr, Andrew Morton , netdev@vger.kernel.org, bugzilla-daemon@bugzilla.kernel.org, bugme-daemon@bugzilla.kernel.org Subject: Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb In-Reply-To: Message-ID: References: <1303183217.4152.49.camel@edumazet-laptop> <1303244270.2756.3.camel@edumazet-laptop> <4DAE901C.2090809@cs.helsinki.fi> <1303286998.3186.18.camel@edumazet-laptop> <1303290464.3186.32.camel@edumazet-laptop> <1303293765.3186.74.camel@edumazet-laptop> <1303309591.3186.84.camel@edumazet-laptop> <1303311687.3186.100.camel@edumazet-laptop> <1305016988.2614.6.camel@edumazet-laptop> <4DC90D7D.9030808@cs.helsinki.fi> <1305022632.2614.18.camel@edumazet-laptop> <4DC91137.4030109@cs.helsinki.fi> <1305047682.2758.1.camel@edumazet-laptop> User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 Content-ID: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Draft for a patch Subject: slub: Make CONFIG_PAGE_ALLOC work with new fastpath Fastpath can do a speculative access to a page that CONFIG_PAGE_ALLOC may have marked as invalid to retrieve the pointer to the next free object. Probe that address before dereferencing the pointer to the page. All of that needs to occur with interrupts disabled since an interrupt could cause the page status to change (as pointed out by Eric). Signed-off-by: Christoph Lameter --- mm/slub.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2011-05-10 12:35:30.000000000 -0500 +++ linux-2.6/mm/slub.c 2011-05-10 12:38:53.000000000 -0500 @@ -261,6 +261,27 @@ static inline void *get_freepointer(stru return *(void **)(object + s->offset); } +static inline void *get_freepointer_safe(struct kmem_cache *s, void *object) +{ + void *p; + +#ifdef CONFIG_PAGE_ALLOC + unsigned long flags; + + local_irq_save(flags); + + if (probe_kernel_address(object)) + p = NULL; /* Invalid */ + else + p = get_freepointer(s, object); + + local_irq_restore(flags); +#else + p = get_freepointer(s, object); +#endif + return p; +} + static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) { *(void **)(object + s->offset) = fp; @@ -1933,7 +1954,7 @@ redo: if (unlikely(!irqsafe_cpu_cmpxchg_double( s->cpu_slab->freelist, s->cpu_slab->tid, object, tid, - get_freepointer(s, object), next_tid(tid)))) { + get_freepointer_safe(s, object), next_tid(tid)))) { note_cmpxchg_failure("slab_alloc", s, tid); goto redo;