Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp4973587ybb; Tue, 24 Mar 2020 08:38:38 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvavC5DkmJC7nXx9HXLji5VJ+Fz+5uwDm9v3JncrHmpfql1Ky1Seq0yUzraUQOyKCT2KfXG X-Received: by 2002:a05:6830:13da:: with SMTP id e26mr2079958otq.181.1585064317954; Tue, 24 Mar 2020 08:38:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1585064317; cv=none; d=google.com; s=arc-20160816; b=JpOJvC2T5uBieLiuWrG7As4rwvWV9KDY5HufZR3RIre7Ilb5qUu6u5zOfGpdsrHWmi X5/5gPwo/XFglj0y5ICb5guqAcXSMSTeNUSgsvmdrg9cxZnN1mC1MKxUKdaNVSNdpuEw 8WdcYU4zjLgOLYOU83RPwW/XhXntzge54X7GZzToeS2WbqB89eNBd825vQnYcJ/cshwv 90EB7QVvVFmvEXzapXuDRiZdtQFPB18A0QzMBZM8zAvJA0PxVJAqgc/4eRxkqR29e9hi Z5JBVXJS6xchDQPRzYh5oLaHYV9RHPYJ6OGipBVqNCaGmuLfYYza6IPwI1oNGZwKBr/M wm9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=bfhYTk9nn0NwblB8uG8AMMbbeqAdsjRtT2QY+/TptFo=; b=PbyPBongzx6c48Mgwcf1H333Nw6ChQb2Q//URg7FS5xJ2aLycg5NDcU67xGv9FATqp wlsB0lo/g5xVR/WZuECnpsu7vDSNd1iU8awoO7QKo+KirARa7Ntgyh6L7aj4P+lFMt2t v9Ti6+1y9FuEp43xNcT+5HQhb09uLvc4cFB1Tec2sV2Cap7U+/KuPTNzUofbyIbBe3uo JXRD6FB2lCropCFlwxsUdqZfhpohsVRAnPpAiGm7dV7sa4ulLzozr6sXQy0o6lUerc1h M6AScdxm3fzWrtQStRJd/ge7+JbRVQhKaIJ+va50Z5DSkoyNI5IgjVZaA/sVjJd49XVs 5/Ew== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=YVd4cx+d; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 50si5174283otv.259.2020.03.24.08.38.25; Tue, 24 Mar 2020 08:38:37 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=YVd4cx+d; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728749AbgCXPhl (ORCPT + 99 others); Tue, 24 Mar 2020 11:37:41 -0400 Received: from mail.kernel.org ([198.145.29.99]:60620 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727857AbgCXPhh (ORCPT ); Tue, 24 Mar 2020 11:37:37 -0400 Received: from localhost.localdomain (236.31.169.217.in-addr.arpa [217.169.31.236]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 9701E208DB; Tue, 24 Mar 2020 15:37:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1585064257; bh=JiMaCGA20Xf9Oah3yv0sde3pP3KYH4qj5+3w+Wbfcto=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YVd4cx+dxJAQ7qFcgpH/vBm98OPGuI81muj23xFNKay798fqF+Oyuv7qdhlj3AL3W djrHKLzyZIKD/ezP9xZrsYdOYErUiqoZSMpSo6Nam4vjZv8u2bIFmAJSgjrvyYN7PW T7mHC8dL0d/CqZvSfNFImHdPgcnawJOeQs3zxDz4= From: Will Deacon To: linux-kernel@vger.kernel.org Cc: Will Deacon , Eric Dumazet , Jann Horn , Kees Cook , Maddie Stone , Marco Elver , "Paul E . McKenney" , Peter Zijlstra , Thomas Gleixner , kernel-team@android.com, kernel-hardening@lists.openwall.com Subject: [RFC PATCH 19/21] list_bl: Extend integrity checking to cover the same cases as 'hlist' Date: Tue, 24 Mar 2020 15:36:41 +0000 Message-Id: <20200324153643.15527-20-will@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200324153643.15527-1-will@kernel.org> References: <20200324153643.15527-1-will@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The list integrity checks for 'hlist_bl' are missing a number of cases that are covered by other list implementations (e.g. 'hlist'), such as validating 'next' and 'pprev' pointers when adding and deleting nodes. Extend the list_bl integrity checks to bring them up to the same level as for other list implementations. Cc: Kees Cook Cc: Paul E. McKenney Cc: Peter Zijlstra Signed-off-by: Will Deacon --- lib/list_debug.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/lib/list_debug.c b/lib/list_debug.c index 9591fa6c9337..3be50b5c8014 100644 --- a/lib/list_debug.c +++ b/lib/list_debug.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -190,27 +191,58 @@ EXPORT_SYMBOL(__hlist_nulls_del_valid); bool __hlist_bl_add_head_valid(struct hlist_bl_node *new, struct hlist_bl_head *head) { + struct hlist_bl_node *first = hlist_bl_first(head); unsigned long hlock = (unsigned long)head->first & LIST_BL_LOCKMASK; unsigned long nlock = (unsigned long)new & LIST_BL_LOCKMASK; - return !(CHECK_DATA_CORRUPTION(nlock, + if (CHECK_DATA_CORRUPTION(nlock, "hlist_bl_add_head: node is locked\n") || - CHECK_DATA_CORRUPTION(hlock != LIST_BL_LOCKMASK, - "hlist_bl_add_head: head is unlocked\n")); + CHECK_DATA_CORRUPTION(hlock != LIST_BL_LOCKMASK, + "hlist_bl_add_head: head is unlocked\n")) + return false; + + if (CHECK_DATA_CORRUPTION(first && first->pprev != &head->first, + "hlist_bl_add_head corruption: first->pprev should be &head->first (%px), but was %px (first=%px)", + &head->first, first->pprev, first) || + CHECK_DATA_CORRUPTION(new == first, + "hlist_bl_add_head double add: new (%px) == first (%px)", + new, first)) + return false; + + return true; } EXPORT_SYMBOL(__hlist_bl_add_head_valid); bool __hlist_bl_del_valid(struct hlist_bl_node *node) { + struct hlist_bl_node *prev, *next = node->next; unsigned long nlock = (unsigned long)node & LIST_BL_LOCKMASK; + unsigned long pnext; - return !(CHECK_DATA_CORRUPTION(nlock, - "hlist_bl_del_valid: node locked") || - CHECK_DATA_CORRUPTION(node->next == LIST_POISON1, + if (CHECK_DATA_CORRUPTION(nlock, + "hlist_bl_del corruption: node is locked") || + CHECK_DATA_CORRUPTION(next == LIST_POISON1, "hlist_bl_del corruption, %px->next is LIST_POISON1 (%px)\n", node, LIST_POISON1) || - CHECK_DATA_CORRUPTION(node->pprev == LIST_POISON2, + CHECK_DATA_CORRUPTION(node->pprev == LIST_POISON2, "hlist_bl_del corruption, %px->pprev is LIST_POISON2 (%px)\n", - node, LIST_POISON2)); + node, LIST_POISON2)) + return false; + + BUILD_BUG_ON(offsetof(struct hlist_bl_node, next) != + offsetof(struct hlist_bl_head, first)); + prev = container_of(node->pprev, struct hlist_bl_node, next); + pnext = (unsigned long)prev->next & ~LIST_BL_LOCKMASK; + if (CHECK_DATA_CORRUPTION((unsigned long)next & LIST_BL_LOCKMASK, + "hlist_bl_del_corruption: node->next is locked") || + CHECK_DATA_CORRUPTION((struct hlist_bl_node *)pnext != node, + "hlist_bl_del corruption: prev->next should be %px, but was %lx\n", + node, pnext) || + CHECK_DATA_CORRUPTION(next && next->pprev != &node->next, + "hlist_bl_del corruption: next->pprev should be %px, but was %px\n", + &node->next, next->pprev)) + return false; + + return true; } EXPORT_SYMBOL(__hlist_bl_del_valid); -- 2.20.1