Received: by 2002:a6b:500f:0:0:0:0:0 with SMTP id e15csp2699596iob; Mon, 16 May 2022 04:25:40 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxgJWxNsnehn124Csc6XZg9pe9D9g/ddpNLunF3t4bTmM1QOwJHwwjSkcwKL8J3UA2mejCh X-Received: by 2002:a17:906:4fc4:b0:6da:b4c6:fadb with SMTP id i4-20020a1709064fc400b006dab4c6fadbmr14976384ejw.282.1652700340322; Mon, 16 May 2022 04:25:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1652700340; cv=none; d=google.com; s=arc-20160816; b=uc1kCVWawG5MunqYH2022VvRmO4uVdobf2XBONr8fnO9Y26Hp58Ph1GZUi6CIqJAo0 Yt208rBHjsGBFHWLMjA/AJvft38DFA3j8wZB6US3nO27teLqyyFMB0XQssTR3JdQNYYR 661hu0jUGm9heUIkLqF3WrfRknMlYosF/j/0/sGVM6iQK7DWKGsz48hOkPY5s65zBHXy VC2w1qNybefuvYyh99O3e/ERPVCtEcMkRa2sdSu6Oy+YoCq4yld0ukhgDbdk7epUSp0J gtc1hudts+p2d7/ix42cd2WvNt6vxhzcn5/WDXkri/4czXGDinGfmEm9JzOaymFSn9EU mWFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:references :in-reply-to:subject:cc:to:dkim-signature:dkim-signature:from; bh=E7coA4n0dI3fqeFnc8eo8/SPSzp9dmnMdNF96cR4v+Q=; b=X7ZOXQa0CEXM1ePOSZooZrJ+WD82pN9wGmySn9/RCEEPDPCv70gi+k722tl8K2iQDx 6KS1ptR/yAaHP5ApE70oEdjQ1S0uKHDVOvMvJag0uo9bNFgzrQoeQFwnEAMSh3l2smyg ZFhgOJIBEbI8FiyTwSD0M6A9thswXq2vGFYIvoigcaQNy67iMgmuJJlhzM0TWzfKJRft oFH8MKyNW8zE99tFZyz8lUfylwMvY0rpyw7SHFHIFCzNUSeAUuaqUeTh0AIqio1/zZgR LKAH0FKQiZBR/SFmtpbshqeMBp5e7qm/ldIkRiju3SIl1I0CJl5qEtZ0IPoMouEeuEvs MzQw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=reJMpeQ9; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y12-20020a056402358c00b00427c9162d00si11540959edc.23.2022.05.16.04.24.52; Mon, 16 May 2022 04:25:40 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=reJMpeQ9; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236549AbiEOLjj (ORCPT + 99 others); Sun, 15 May 2022 07:39:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236512AbiEOLji (ORCPT ); Sun, 15 May 2022 07:39:38 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F05B23B02A for ; Sun, 15 May 2022 04:39:36 -0700 (PDT) From: Thomas Gleixner DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1652614775; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=E7coA4n0dI3fqeFnc8eo8/SPSzp9dmnMdNF96cR4v+Q=; b=reJMpeQ91nOn88ki2cd7jTX8T5PA6JUA9+8o9tliUsU0RHuAniceU/HeHcb5PXj3cjHM73 EJjijl65+fV8ErhfU22eoZcYXinl7/KKmClDCv3Zl8XkJygz6NAo3/EtscTAoe8iniaM3u SF2+iOGLgxPrE0JnkoxK+wDXknxhkzem8Fnr7ZS+Ajwdn0boWUA4u3Ml8DxxpHspxXUpRs PIQKqwC3t6Tu9hrcJOsph+fLEcglTpaigN7iAGgHC2CFmXEn6X4by8JETh3/Fx4IFUdnQ9 CjnF9RfGIKT9qK69wNgmv65H9x5e9+O6yIzaTignaiLo4TvI6UfWZHM2BDlNMQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1652614775; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=E7coA4n0dI3fqeFnc8eo8/SPSzp9dmnMdNF96cR4v+Q=; b=OVT9LHoMA95dMXQbGub7KwAHvDmXULy5xfgoflBTVBR0aV164hpD//bhFG1Z5uJuAw52ZG WvO1j/g3aGj2VPCA== To: Sean Christopherson , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org Cc: "H. Peter Anvin" , linux-kernel@vger.kernel.org, "Guilherme G . Piccoli" , Vitaly Kuznetsov , Paolo Bonzini , Sean Christopherson Subject: [PATCH V2] x86/nmi: Make register_nmi_handler() more robust In-Reply-To: <87zgjlsn75.ffs@tglx> References: <20220511234332.3654455-1-seanjc@google.com> <87zgjlsn75.ffs@tglx> Date: Sun, 15 May 2022 13:39:34 +0200 Message-ID: <87tu9rqb2h.ffs@tglx> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org register_nmi_handler() has no sanity check whether a handler has been registered already. Such an unintended double-add leads to list corruption and hard to diagnose problems during the next NMI handling. Init the list head in the static nmi action struct and check it for being empty in register_nmi_handler(). Reported-by: Sean Christopherson Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/lkml/20220511234332.3654455-1-seanjc@google.com --- V2: Warn if no handler provided and not for the correct case (Boris) --- arch/x86/include/asm/nmi.h | 1 + arch/x86/kernel/nmi.c | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h @@ -47,6 +47,7 @@ struct nmiaction { #define register_nmi_handler(t, fn, fg, n, init...) \ ({ \ static struct nmiaction init fn##_na = { \ + .list = LIST_HEAD_INIT(fn##_na.list), \ .handler = (fn), \ .name = (n), \ .flags = (fg), \ --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -157,7 +157,7 @@ int __register_nmi_handler(unsigned int struct nmi_desc *desc = nmi_to_desc(type); unsigned long flags; - if (!action->handler) + if (WARN_ON_ONCE(!action->handler || !list_empty(&action->list))) return -EINVAL; raw_spin_lock_irqsave(&desc->lock, flags); @@ -186,7 +186,7 @@ EXPORT_SYMBOL(__register_nmi_handler); void unregister_nmi_handler(unsigned int type, const char *name) { struct nmi_desc *desc = nmi_to_desc(type); - struct nmiaction *n; + struct nmiaction *n, *found = NULL; unsigned long flags; raw_spin_lock_irqsave(&desc->lock, flags); @@ -200,12 +200,16 @@ void unregister_nmi_handler(unsigned int WARN(in_nmi(), "Trying to free NMI (%s) from NMI context!\n", n->name); list_del_rcu(&n->list); + found = n; break; } } raw_spin_unlock_irqrestore(&desc->lock, flags); - synchronize_rcu(); + if (found) { + synchronize_rcu(); + INIT_LIST_HEAD(found); + } } EXPORT_SYMBOL_GPL(unregister_nmi_handler);