From patchwork Fri Oct 18 09:42:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197967 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2A8BA14ED for ; Fri, 18 Oct 2019 09:43:20 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id E1A3F20820 for ; Fri, 18 Oct 2019 09:43:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="GkHGImpL" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E1A3F20820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 150FE8E001C; Fri, 18 Oct 2019 05:43:19 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 1019B8E0003; Fri, 18 Oct 2019 05:43:19 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 017BF8E001C; Fri, 18 Oct 2019 05:43:18 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0059.hostedemail.com [216.40.44.59]) by kanga.kvack.org (Postfix) with ESMTP id D4C198E0003 for ; Fri, 18 Oct 2019 05:43:18 -0400 (EDT) Received: from smtpin06.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with SMTP id 77A0D180619D6 for ; Fri, 18 Oct 2019 09:43:18 +0000 (UTC) X-FDA: 76056417276.06.ship27_74229d40f9a33 X-Spam-Summary: 2,0,0,b48b28dab49ff4a9,d41d8cd98f00b204,3nimpxqykcn8hmjefshpphmf.dpnmjovy-nnlwbdl.psh@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:2393:2559:2562:3138:3139:3140:3141:3142:3152:3352:3866:3867:4321:4605:5007:6120:6261:6642:6653:7901:8603:9969:10004:10400:11026:11232:11473:11658:11914:12043:12296:12297:12438:12555:12895:12986:13069:13255:13311:13357:13846:14181:14394:14659:14721:21080:21365:21444:21451:21627:30054:30064:30070:30080,0,RBL:209.85.221.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.175.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:30,LUA_SUMMARY:none X-HE-Tag: ship27_74229d40f9a33 X-Filterd-Recvd-Size: 3953 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf37.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:17 +0000 (UTC) Received: by mail-wr1-f73.google.com with SMTP id t11so2341505wro.10 for ; Fri, 18 Oct 2019 02:43:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=qVGfiBfhzzQVnou2oLJwveorzbwo6gIrrMhVCSkMAIo=; b=GkHGImpLQ3EwRKwn7l/ZADn4OVLW423JyxDFc1LdBHQMA7HPpTP9LYR9WqXImI1U03 c3/UcJwjyXMvEQmDqQz6dNQdWACd8ALvcjFiLg/UqYH83RTi6ZEZzjGH5EKWA2kReu09 0cCmLuuoFx7CrUoRNz57xWwr+p2edFNTlAbSYZX7SDfwWxUG6qfVZw42TGCGAGSEtT4A a83wM9jW0ZmfXSXIPz6aswrU4H3hYKDL8XGJynoXzdcdD2fw5my0lTPuJQ3nCUroL23E 5QfnSe7XvOjYxZNIMZSAVhxKOsi/+/XkjwIZni/DvVjughveQILrBtvHCDs2uh0O7qwR iDjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=qVGfiBfhzzQVnou2oLJwveorzbwo6gIrrMhVCSkMAIo=; b=F8KdgTS7O4UcHVF/2z7G0j5cIJuLXqcEhk0rvZGyNmU36hjtJx5Y1cSKpJ9q7lEySV SwiNizLzx9hOovIOw1YkAYAwaMeGpnD+XDBJJBCmlQBPSJvdUCTjVqWR85oOsWkCtFHt zMR7IyN2637Re/Cwap5TJU8Wqj+IfwFFECP3Yhmgo2TmOmR37vKGWTNsAU5cR+Xw0pPf JV7RxW0YEl6CyV0SC3mxo3Q4DCZYrYEtVZETOge4le2YLJp4WWVMRufFrToibgd979wk nfMT1TsoIaq7Tkxgq+UC98MrNUdjAOGvFc4usxIWrGPyXcESgtny9hw0bBk4rCFZwQep xPyA== X-Gm-Message-State: APjAAAUZP0lYSd/T0d7mSnleWfBrtyVaF03qkWfU76KgN2Atd1gqLAfe RJulpIqGHqvmvRQUuVN1WTYYZaiQwO0= X-Google-Smtp-Source: APXvYqwaWTNi0Of8RXmiHbm8De8QIudp9h9GWyZYJ7B+VS6uSbe2nnu5rdh16diWDy6Kw/3c1jGdAzVwDFo= X-Received: by 2002:a5d:6246:: with SMTP id m6mr1325165wrv.262.1571391796358; Fri, 18 Oct 2019 02:43:16 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:39 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-2-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 01/26] stackdepot: check depot_index before accessing the stack slab From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Avoid crashes on corrupted stack ids. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I0a0b38ed5057090696a2c6ff0be7cfcc24ae6738 --- lib/stackdepot.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/stackdepot.c b/lib/stackdepot.c index ed717dd08ff3..0d00d2ac0c4b 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -198,9 +198,22 @@ unsigned int stack_depot_fetch(depot_stack_handle_t handle, unsigned long **entries) { union handle_parts parts = { .handle = handle }; - void *slab = stack_slabs[parts.slabindex]; + void *slab; size_t offset = parts.offset << STACK_ALLOC_ALIGN; - struct stack_record *stack = slab + offset; + struct stack_record *stack; + + if (parts.slabindex > depot_index) { + WARN(1, "slab index %d out of bounds (%d) for stack id %08x\n", + parts.slabindex, depot_index, handle); + __memset(trace, 0, sizeof(*trace)); + return; + } + slab = stack_slabs[parts.slabindex]; + stack = slab + offset; + if (!stack) { + entries = NULL; + return 0; + } *entries = stack->entries; return stack->size; From patchwork Fri Oct 18 09:42:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197969 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0428713B1 for ; Fri, 18 Oct 2019 09:43:23 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id C547120820 for ; Fri, 18 Oct 2019 09:43:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Gjvxkoo5" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C547120820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id A9FFE8E001D; Fri, 18 Oct 2019 05:43:21 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id A50638E0003; Fri, 18 Oct 2019 05:43:21 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 940678E001D; Fri, 18 Oct 2019 05:43:21 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0185.hostedemail.com [216.40.44.185]) by kanga.kvack.org (Postfix) with ESMTP id 745038E0003 for ; Fri, 18 Oct 2019 05:43:21 -0400 (EDT) Received: from smtpin02.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with SMTP id 1A4868120 for ; Fri, 18 Oct 2019 09:43:21 +0000 (UTC) X-FDA: 76056417402.02.plot79_748340a29c42a X-Spam-Summary: 2,0,0,16eef29cc3a1ffdd,d41d8cd98f00b204,3n4mpxqykcoikpmhivksskpi.gsqpmryb-qqozego.svk@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:2393:2553:2559:2562:3138:3139:3140:3141:3142:3152:3352:3867:3871:4321:5007:6120:6261:6653:7901:8660:9969:10004:10400:11232:11658:11914:12043:12297:12438:12555:12895:12986:13069:13148:13230:13255:13311:13357:13846:14096:14097:14181:14394:14659:14721:21080:21365:21444:21451:21627:30054:30064:30090,0,RBL:209.85.221.74:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.175.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:24,LUA_SUMMARY:none X-HE-Tag: plot79_748340a29c42a X-Filterd-Recvd-Size: 3622 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) by imf06.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:20 +0000 (UTC) Received: by mail-wr1-f74.google.com with SMTP id j7so2361948wrx.14 for ; Fri, 18 Oct 2019 02:43:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=b4sChJXo02GMyut/YFGQ6mxS+lMlTs8aNndVBMC32OI=; b=Gjvxkoo59MdlloiTM6XPIn3mnv04l/FqNhlHZ8i4inrEDMkNRxx4yuh043zxFxE8Yl 9a6K49Gz7+hg33BzipaYe5ttRLaZaqJcJ2/76tRKLa/Hd6rwCq3AqsGmrCtW3Rpvxae/ FZffIDvDgHSrnLv6DrNdwIHSLR7gCsapoU7jUplcY6T/cSRtaNMYIILsl3m0GfPWhlrB 5J6PIS7CNp4/kl63dRqJ5icb37Rn6mrckoHBkcybNTqKs6xBbDJezc1a6O1xWEkT1Zha ZKzDh0oZlZYOlBoNki5tbquoZC+LpA72rTeGFAJsqkzaCOrZ0XbeaFFXlIh+IleSqGAy uWlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=b4sChJXo02GMyut/YFGQ6mxS+lMlTs8aNndVBMC32OI=; b=ieSx/d8tB95d3z1l3FdSAcjtH/mnWAGSLGgOemV9Dw7EySQWmmMRmC8QjFYhdAObIW tgFvywtXwE4m9vUVRqeci4LVHWflmjECRelV3wWpeftDIkbliIM2A7KNI5bmtEGHMw6P pu2Lt6/Bs57fYKHcPXk8NRW9M5pDV/hD0R2ScIiJQq6H6N7K1ym2+9RIuvg96rqPG4wP RDAQcBed6pjhAT6tu26vgLVX8jMqZDT6LN3QZkhpT2UqZyNKArUWwzQ7nztCGGEeQ7Ga TwEm9N7ao+yfUU+gRvFAji4J240dgO44exQVQ9Mo6xTeLKIy/cP1YBQZDNIV3NFYwTPV ni1A== X-Gm-Message-State: APjAAAWcc0owUe8jXSeSYix0mT4AAGsOWbmv+tOXkzpE052Lr0dJhtr/ she2+oskhm5Fc5J8nvlI3zC5q4IbxN0= X-Google-Smtp-Source: APXvYqwfuIm6Jky5B+mMFheFgCgSu6sIwMNikNBnQmcmJmk7kz449WuoYJk9wyi5g1p3huyFvshmB+Rk/Po= X-Received: by 2002:a5d:6785:: with SMTP id v5mr4178057wru.174.1571391799447; Fri, 18 Oct 2019 02:43:19 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:40 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-3-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 02/26] stackdepot: prevent Clang from optimizing away stackdepot_memcmp() From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Clang may replace stackdepot_memcmp() with a call to instrumented bcmp(), which is exactly what we wanted to avoid creating stackdepot_memcmp(). Add a compiler barrier() to prevent optimizations. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I4495b617b15c0ab003a61c1f0d54d0026fa8b144 --- lib/stackdepot.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/stackdepot.c b/lib/stackdepot.c index 0d00d2ac0c4b..785839298e08 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -163,6 +163,11 @@ int stackdepot_memcmp(const unsigned long *u1, const unsigned long *u2, unsigned int n) { for ( ; n-- ; u1++, u2++) { + /* + * Prevent Clang from replacing this function with a bcmp() + * call. + */ + barrier(); if (*u1 != *u2) return 1; } From patchwork Fri Oct 18 09:42:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197971 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1B94B13B1 for ; Fri, 18 Oct 2019 09:43:26 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id CEFDB21D7C for ; Fri, 18 Oct 2019 09:43:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="FJVwfg26" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CEFDB21D7C Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id A9FFE8E001E; Fri, 18 Oct 2019 05:43:24 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id A50B08E0003; Fri, 18 Oct 2019 05:43:24 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 966418E001E; Fri, 18 Oct 2019 05:43:24 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0125.hostedemail.com [216.40.44.125]) by kanga.kvack.org (Postfix) with ESMTP id 755648E0003 for ; Fri, 18 Oct 2019 05:43:24 -0400 (EDT) Received: from smtpin08.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with SMTP id 246A98120 for ; Fri, 18 Oct 2019 09:43:24 +0000 (UTC) X-FDA: 76056417528.08.woman04_74efd37b7322b X-Spam-Summary: 2,0,0,4faec83f417ea76f,d41d8cd98f00b204,3oompxqykcounspklynvvnsl.jvtspube-ttrchjr.vyn@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:aryabinin@virtuozzo.com:,RULES_HIT:41:69:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1535:1543:1593:1594:1711:1730:1747:1777:1792:2393:2559:2562:2904:3138:3139:3140:3141:3142:3152:3353:3865:3866:3867:3871:3872:4117:4321:4605:5007:6119:6120:6261:6653:7901:7903:9592:9969:10004:10400:11026:11232:11233:11473:11658:11914:12043:12291:12297:12438:12555:12895:12986:13255:13846:14181:14394:14659:14721:21080:21365:21433:21444:21451:21611:21627:30025:30054:30064,0,RBL:209.85.128.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:24,LUA_SUMMARY:none X-HE-Tag: woman04_74efd37b7322b X-Filterd-Recvd-Size: 6050 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf09.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:23 +0000 (UTC) Received: by mail-wm1-f73.google.com with SMTP id g67so2082155wmg.4 for ; Fri, 18 Oct 2019 02:43:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=SsMz7eFltn0ZjkiCW0+3yiX/vX8A/Koa4q1zO46yHhw=; b=FJVwfg269wcr/WgBNlPHCjiYAL+Qtg2aXTbwHjxbp7Br4i9h9bG67UiqfWEstLIsJl DuoILMT3SyW+Uu9OKnxEeZTL4CGJQ4yVa7ffWH37Ew5YWe4+zF5tsVKQarrkK7QZOw4t CnxcZp/kDbnUqVmhDL1wlwfLCEuHc/f+Kg/8U58iCN/tPtm67xeMTLbNZe+GJYbP+FRY dKBFv/GZVewemNqvBG/TWOozOOhG8ZTcYc38H1ZyW6UXluypomHr6/rWCS3UG+VubqTO q4Nr5+clCaJKI5+w0kvKsI2cn5fparsCpSY7Tv2BWkbYEhEr81JpdN4SKRt+CcQKngQX QHDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=SsMz7eFltn0ZjkiCW0+3yiX/vX8A/Koa4q1zO46yHhw=; b=GgT6F782IWWtpEPzv469XE1MDUiHS+Xr1L7+B45gyLNj4Jd/wTV/F4c+xGqehWAFHC 6qk+428lp5ETofbrVEJ/LhcBoUaL9wxh9g6up2HidSQVKU0a2nOGBLQMBbL5746gsHJ4 JhSJaq/jFEcdSqr2p55RFePnoFK6PxFvrIIw1sdV5cdHjIy5s75I629OZcR7dT2fQ4Jj gtc61NEMjSAP/1zR/r02la9WErMY/G8/qTAOjmjA8wXIuk74eprETSZlUtDBwAsGD+OX u+1OioQSgpAGdTZbBNw3WG3rr/AF3WH7H0rZpwanoUr09z8Us+UVTeDwChhlVUQIyWAX F3dA== X-Gm-Message-State: APjAAAWdaTXIGNVxQ7HOZEp39MIWzhPuXG9OJBt7V3kMLciyFLFa1ZEn 30sfWNeHa1j+XFmVqFv2q81ta0awopY= X-Google-Smtp-Source: APXvYqy27kntIt5Ffh34kSohXEXc5I8BmwVtkfzGNd632Jhc7GpN9lL0PWOdUQpoj8i6qrGZSvMaJvY2yRE= X-Received: by 2002:a5d:63cf:: with SMTP id c15mr1423996wrw.89.1571391802198; Fri, 18 Oct 2019 02:43:22 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:41 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-4-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 03/26] kasan: stackdepot: move filter_irq_stacks() to stackdepot.c From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , Andrey Ryabinin , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: filter_irq_stacks() can be used by other tools (e.g. KMSAN), so it needs to be moved to a common location. lib/stackdepot.c seems a good place, as filter_irq_stacks() is usually applied to the output of stack_trace_save(). Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: Andrey Ryabinin Cc: linux-mm@kvack.org --- Change-Id: I65acecf64930a3658e8c2aa7423801082ded8602 --- include/linux/stackdepot.h | 2 ++ lib/stackdepot.c | 23 +++++++++++++++++++++++ mm/kasan/common.c | 23 ----------------------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/include/linux/stackdepot.h b/include/linux/stackdepot.h index 3efa97d482cb..24d49c732341 100644 --- a/include/linux/stackdepot.h +++ b/include/linux/stackdepot.h @@ -19,4 +19,6 @@ depot_stack_handle_t stack_depot_save(unsigned long *entries, unsigned int stack_depot_fetch(depot_stack_handle_t handle, unsigned long **entries); +unsigned int filter_irq_stacks(unsigned long *entries, unsigned int nr_entries); + #endif diff --git a/lib/stackdepot.c b/lib/stackdepot.c index 785839298e08..decb1e073b58 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -319,3 +320,25 @@ depot_stack_handle_t stack_depot_save(unsigned long *entries, return retval; } EXPORT_SYMBOL_GPL(stack_depot_save); + +static inline int in_irqentry_text(unsigned long ptr) +{ + return (ptr >= (unsigned long)&__irqentry_text_start && + ptr < (unsigned long)&__irqentry_text_end) || + (ptr >= (unsigned long)&__softirqentry_text_start && + ptr < (unsigned long)&__softirqentry_text_end); +} + +unsigned int filter_irq_stacks(unsigned long *entries, + unsigned int nr_entries) +{ + unsigned int i; + + for (i = 0; i < nr_entries; i++) { + if (in_irqentry_text(entries[i])) { + /* Include the irqentry function into the stack. */ + return i + 1; + } + } + return nr_entries; +} diff --git a/mm/kasan/common.c b/mm/kasan/common.c index 6814d6d6a023..154eba5700d8 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include @@ -39,28 +38,6 @@ #include "kasan.h" #include "../slab.h" -static inline int in_irqentry_text(unsigned long ptr) -{ - return (ptr >= (unsigned long)&__irqentry_text_start && - ptr < (unsigned long)&__irqentry_text_end) || - (ptr >= (unsigned long)&__softirqentry_text_start && - ptr < (unsigned long)&__softirqentry_text_end); -} - -static inline unsigned int filter_irq_stacks(unsigned long *entries, - unsigned int nr_entries) -{ - unsigned int i; - - for (i = 0; i < nr_entries; i++) { - if (in_irqentry_text(entries[i])) { - /* Include the irqentry function into the stack. */ - return i + 1; - } - } - return nr_entries; -} - static inline depot_stack_handle_t save_stack(gfp_t flags) { unsigned long entries[KASAN_STACK_DEPTH]; From patchwork Fri Oct 18 09:42:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197973 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2579614ED for ; Fri, 18 Oct 2019 09:43:29 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id D03BC20820 for ; Fri, 18 Oct 2019 09:43:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="lhD6wCKe" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D03BC20820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 859F88E001F; Fri, 18 Oct 2019 05:43:27 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 7B96B8E0003; Fri, 18 Oct 2019 05:43:27 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6FBF28E001F; Fri, 18 Oct 2019 05:43:27 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0222.hostedemail.com [216.40.44.222]) by kanga.kvack.org (Postfix) with ESMTP id 45BF38E0003 for ; Fri, 18 Oct 2019 05:43:27 -0400 (EDT) Received: from smtpin08.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with SMTP id CDCA6181B8ACC for ; Fri, 18 Oct 2019 09:43:26 +0000 (UTC) X-FDA: 76056417612.08.group02_7555b7c2be250 X-Spam-Summary: 2,0,0,2ca656a86020b7b0,d41d8cd98f00b204,3pympxqykcogqvsnobqyyqvo.mywvsxeh-wwufkmu.ybq@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1535:1543:1593:1594:1711:1730:1747:1777:1792:2198:2199:2393:2553:2559:2562:2892:2901:3138:3139:3140:3141:3142:3152:3353:3865:3866:3867:3868:3870:3874:4117:4321:4605:5007:6120:6261:6653:7875:7901:8603:9036:9969:10004:10400:11026:11232:11473:11658:11914:12043:12114:12291:12296:12297:12438:12555:12895:12986:13846:14096:14097:14181:14394:14659:14721:21080:21365:21444:21451:21627:30034:30054:30064:30075:30090,0,RBL:209.85.221.74:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.175.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:26,LUA_SUMMARY:none X-HE-Tag: group02_7555b7c2be250 X-Filterd-Recvd-Size: 6059 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) by imf16.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:26 +0000 (UTC) Received: by mail-wr1-f74.google.com with SMTP id k4so2357027wru.1 for ; Fri, 18 Oct 2019 02:43:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=gPdX/WRj8pZ6Op0hb7v4T/s2H3li4wgFIxE7iLwlBqM=; b=lhD6wCKe/yLpEt6Bnd+BlFsV1+akfNEhtbT6KJMPQ3puuv/hbRWfLQP0YQzhYfGWc9 0JNGR3ahQxZbq+XbkBO5ZjcvA3MpX8QQeV7eQ9YAEsH6a6c7PW/ibqD8d1t94mWDyu9v RZ0p4cJ7mYbdS+esL2vy0USBuKcRW1lh/VrkbklswLO+9T/ZdgHa/+v1fvpxoFxSilaN Kx0WR+Ymdch/kLCaxJ/neGQZgB5qLAnae85csjOuIApZm8A/A0M654/r1sIMVm7DYNZY QRCOBAmfCza222lUyDWPiMBiyznIL+4SkL++YhNMDMd18A2+xhdlqyz3mVcQoQju9ooo gKcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=gPdX/WRj8pZ6Op0hb7v4T/s2H3li4wgFIxE7iLwlBqM=; b=ryzqz7BhCZVEkRhsF+8fHCIGIEJtrc63OEQP/wLPOpDG5MT9LwKDXhgWxIRIds3RH8 PU1+nd7KKxf1N5CjLaOynxD2/TH4VtDfCQK84ibPSerJkrQSUPhApraRrlxy5xQ3aVpn nc0MmBZdicTEzr64SH9nGqvads0CweP885WoAv/v+ps7q8CXALEj2aPHB2ETHFYsWG67 c80+qqReowmm5NNLu/1I2lHmxw3N9ygxiHk9uW2j8obvimBSA+i+iy1gySywgo1j7ZzE wu3RGJL8rJb3dTBTH0hW3XDiO9if9WbSMHKxxVOCUeTqjIP+2aUGDD1T2b1uF9RIt+S2 bE2w== X-Gm-Message-State: APjAAAW2NNHCExzvmoVF655BFscABf4wfTnR3eOXgYXkzjS7H0EDCiio 2SybY5IYbs1iOYrGewaf1M/L5orFkAQ= X-Google-Smtp-Source: APXvYqy+p8Fpj+OUm4Ang53HP5c68oXbPSGU4QKJS7p0bYETpigwn3HFUFX2stkzOG/zlSanfyHpKarBwmw= X-Received: by 2002:a5d:4b4c:: with SMTP id w12mr6711737wrs.107.1571391805152; Fri, 18 Oct 2019 02:43:25 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:42 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-5-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 04/26] stackdepot: reserve 5 extra bits in depot_stack_handle_t From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Some users (currently only KMSAN) may want to use spare bits in depot_stack_handle_t. Let them do so and provide get_dsh_extra_bits() and set_dsh_extra_bits() to access those bits. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I23580dbde85908eeda0bdd8f83a8c3882ab3e012 --- include/linux/stackdepot.h | 8 ++++++++ lib/stackdepot.c | 24 +++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/include/linux/stackdepot.h b/include/linux/stackdepot.h index 24d49c732341..ac1b5a78d7f6 100644 --- a/include/linux/stackdepot.h +++ b/include/linux/stackdepot.h @@ -12,6 +12,11 @@ #define _LINUX_STACKDEPOT_H typedef u32 depot_stack_handle_t; +/* + * Number of bits in the handle that stack depot doesn't use. Users may store + * information in them. + */ +#define STACK_DEPOT_EXTRA_BITS 5 depot_stack_handle_t stack_depot_save(unsigned long *entries, unsigned int nr_entries, gfp_t gfp_flags); @@ -20,5 +25,8 @@ unsigned int stack_depot_fetch(depot_stack_handle_t handle, unsigned long **entries); unsigned int filter_irq_stacks(unsigned long *entries, unsigned int nr_entries); +depot_stack_handle_t set_dsh_extra_bits(depot_stack_handle_t handle, + unsigned int bits); +unsigned int get_dsh_extra_bits(depot_stack_handle_t handle); #endif diff --git a/lib/stackdepot.c b/lib/stackdepot.c index decb1e073b58..460efd3ef742 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -40,8 +40,10 @@ #define STACK_ALLOC_ALIGN 4 #define STACK_ALLOC_OFFSET_BITS (STACK_ALLOC_ORDER + PAGE_SHIFT - \ STACK_ALLOC_ALIGN) + #define STACK_ALLOC_INDEX_BITS (DEPOT_STACK_BITS - \ - STACK_ALLOC_NULL_PROTECTION_BITS - STACK_ALLOC_OFFSET_BITS) + STACK_ALLOC_NULL_PROTECTION_BITS - \ + STACK_ALLOC_OFFSET_BITS - STACK_DEPOT_EXTRA_BITS) #define STACK_ALLOC_SLABS_CAP 8192 #define STACK_ALLOC_MAX_SLABS \ (((1LL << (STACK_ALLOC_INDEX_BITS)) < STACK_ALLOC_SLABS_CAP) ? \ @@ -54,6 +56,7 @@ union handle_parts { u32 slabindex : STACK_ALLOC_INDEX_BITS; u32 offset : STACK_ALLOC_OFFSET_BITS; u32 valid : STACK_ALLOC_NULL_PROTECTION_BITS; + u32 extra : STACK_DEPOT_EXTRA_BITS; }; }; @@ -72,6 +75,24 @@ static int next_slab_inited; static size_t depot_offset; static DEFINE_SPINLOCK(depot_lock); +depot_stack_handle_t set_dsh_extra_bits(depot_stack_handle_t handle, + u32 bits) +{ + union handle_parts parts = { .handle = handle }; + + parts.extra = bits & ((1U << STACK_DEPOT_EXTRA_BITS) - 1); + return parts.handle; +} +EXPORT_SYMBOL_GPL(set_dsh_extra_bits); + +u32 get_dsh_extra_bits(depot_stack_handle_t handle) +{ + union handle_parts parts = { .handle = handle }; + + return parts.extra; +} +EXPORT_SYMBOL_GPL(get_dsh_extra_bits); + static bool init_stack_slab(void **prealloc) { if (!*prealloc) @@ -132,6 +153,7 @@ static struct stack_record *depot_alloc_stack(unsigned long *entries, int size, stack->handle.slabindex = depot_index; stack->handle.offset = depot_offset >> STACK_ALLOC_ALIGN; stack->handle.valid = 1; + stack->handle.extra = 0; memcpy(stack->entries, entries, size * sizeof(unsigned long)); depot_offset += required_size; From patchwork Fri Oct 18 09:42:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197975 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DAAB714ED for ; Fri, 18 Oct 2019 09:43:31 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 9E3F720820 for ; Fri, 18 Oct 2019 09:43:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Qnhdq/up" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9E3F720820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 6A7BD8E0020; Fri, 18 Oct 2019 05:43:30 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 659998E0003; Fri, 18 Oct 2019 05:43:30 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 520698E0020; Fri, 18 Oct 2019 05:43:30 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0108.hostedemail.com [216.40.44.108]) by kanga.kvack.org (Postfix) with ESMTP id 2843D8E0003 for ; Fri, 18 Oct 2019 05:43:30 -0400 (EDT) Received: from smtpin17.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id A76C28120 for ; Fri, 18 Oct 2019 09:43:29 +0000 (UTC) X-FDA: 76056417738.17.wind02_75c45313d401b X-Spam-Summary: 2,0,0,7ec8ef6317632192,d41d8cd98f00b204,3p4mpxqykcoosxupqdsaasxq.oayxuzgj-yywhmow.ads@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:pmladek@suse.com:sergey.senozhatsky@gmail.com:rostedt@goodmis.org:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:2194:2199:2393:2559:2562:3138:3139:3140:3141:3142:3152:3352:3865:3866:3867:3870:4321:5007:6120:6261:6653:7514:7901:9969:10004:10400:11026:11232:11473:11658:11914:12043:12296:12297:12438:12555:12895:12986:13069:13311:13357:13846:14096:14097:14181:14394:14659:14721:21063:21080:21365:21433:21444:21451:21627:30046:30054:30064:30070,0,RBL:209.85.128.74:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:24,LUA_SUMMARY:none X-HE-Tag: wind02_75c45313d401b X-Filterd-Recvd-Size: 3988 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf26.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:29 +0000 (UTC) Received: by mail-wm1-f74.google.com with SMTP id z5so622786wma.5 for ; Fri, 18 Oct 2019 02:43:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=kQAVHdj1ULLW1duUtV+wvhyxEzmEv0/AhXDpZXorHfI=; b=Qnhdq/upJpo+5aEX/OtoVwQZjzU/k74/ZOcdnE3ynaXONWPwKqXTjKMRiLVuZhatDt WwaGBUMRmmJUX5yKGycTRXn/bgnkqOwr9x8q4SwsavE1hrv7j58n0CHgHJYyaSa8EAuZ aJN4ey7G4lBygDoNusFLc7d4aAzRKVqWZH89f3KEv0K1lPFzNbE/TSkatJTCp0kN6/2g gDfUtNXKeGQ9HWgCa/CXGI/SJIMj/HzJTKzS1R0vGfPNJOOcCDwXbvb/kI+RgRNldHNI gMelffsUsq84dsW7kfJiBVhX91twYe6xPGlpUgEobAAd+GCC8lMiArdJVgw3PaKKwhaR PX8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=kQAVHdj1ULLW1duUtV+wvhyxEzmEv0/AhXDpZXorHfI=; b=LjoPjGI6STbNgfQqp0mIr8OPWYIw6BoxITW1oinXeDLY5RMDdzkWjzI8zDbKkIJ00Q 8I7o79DFbGEa0FOEYV9mDAnOxL4UrHdivsWIFEP/PO7QtLzFS1XtXbRXmT+/PlMjQetS W1lfey0iIg5w9TEECPb6E3CpYWf/F+lumK1aLNY5uZEtWK0yeylhT1U7V901Z37uvuhJ M0FlDKlQV/jT/QfiMKHisVO1Yo169uAmVEDnyASonIJocHvcNXdmDJnqsH3uu1yenDM6 mWBuntBCNKoF86L1NiY9j037m40k2A7EQZECE+r4Lbz1VROf22Fk2HYgoC3na+9UulGL 70tA== X-Gm-Message-State: APjAAAXnMjvt+eW77H2z9T/95xtJJP6pTyTOp7aCzbMoIdUPXfwVCG9a 23Z8E361v/l5npDN+7CvQpV9j5LBuvk= X-Google-Smtp-Source: APXvYqxioAg7X687O5rvtifYe7NBFAcRDzwjNK+YtENx4yWZhG1Lg9NUafgZP37yAoPET60yd07IWNBX4u0= X-Received: by 2002:adf:f684:: with SMTP id v4mr1614190wrp.336.1571391807993; Fri, 18 Oct 2019 02:43:27 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:43 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-6-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 05/26] printk_safe: externalize printk_context From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Petr Mladek , Sergey Senozhatsky , Steven Rostedt , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Petr Mladek suggested we use this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK instead of checking the spinlock status in kmsan_pr_err() This appears to be less intrusive, although we'll need to declare printk_context in some printk header. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Petr Mladek Cc: Sergey Senozhatsky Cc: Steven Rostedt Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: Idb5e7c7cedf6ab6ba635a64423d58d702ad3eca3 --- kernel/printk/printk_safe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c index b4045e782743..5ebfc8bc5693 100644 --- a/kernel/printk/printk_safe.c +++ b/kernel/printk/printk_safe.c @@ -42,7 +42,7 @@ struct printk_safe_seq_buf { }; static DEFINE_PER_CPU(struct printk_safe_seq_buf, safe_print_seq); -static DEFINE_PER_CPU(int, printk_context); +DEFINE_PER_CPU(int, printk_context); #ifdef CONFIG_PRINTK_NMI static DEFINE_PER_CPU(struct printk_safe_seq_buf, nmi_print_seq); From patchwork Fri Oct 18 09:42:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197977 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 95F6613B1 for ; Fri, 18 Oct 2019 09:43:34 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 631D820820 for ; Fri, 18 Oct 2019 09:43:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="M1OHTJFs" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 631D820820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id E9FF88E0021; Fri, 18 Oct 2019 05:43:32 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id E6F758E0003; Fri, 18 Oct 2019 05:43:32 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D5E7F8E0021; Fri, 18 Oct 2019 05:43:32 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0231.hostedemail.com [216.40.44.231]) by kanga.kvack.org (Postfix) with ESMTP id B611A8E0003 for ; Fri, 18 Oct 2019 05:43:32 -0400 (EDT) Received: from smtpin02.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id 5B085FB7D for ; Fri, 18 Oct 2019 09:43:32 +0000 (UTC) X-FDA: 76056417864.02.drain46_7627fb41a9548 X-Spam-Summary: 2,0,0,92efe5750802bb21,d41d8cd98f00b204,3q4mpxqykco4wbytuhweewbu.secbydkn-ccalqsa.ehw@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:schwidefsky@de.ibm.com:aryabinin@virtuozzo.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:967:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1535:1543:1593:1594:1711:1730:1747:1777:1792:1981:2194:2199:2393:2525:2553:2559:2563:2682:2685:2859:2899:2933:2937:2939:2942:2945:2947:2951:2954:3022:3138:3139:3140:3141:3142:3152:3354:3865:3866:3867:3868:3871:3872:3874:3934:3936:3938:3941:3944:3947:3950:3953:3956:3959:4250:4321:4605:5007:6119:6120:6261:6653:7901:8603:9025:9969:10004:10400:11026:11232:11473:11657:11658:11914:12043:12114:12296:12297:12438:12555:12698:12737:12895:13180:13229:13255:13846:14096:14097:14181:14394:14659:14721:21080:21365:21444:21451:21627:30029:30054:30064:30070:30090,0,RBL:error,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF :fp,MSBL X-HE-Tag: drain46_7627fb41a9548 X-Filterd-Recvd-Size: 5867 Received: from mail-qk1-f202.google.com (mail-qk1-f202.google.com [209.85.222.202]) by imf29.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:31 +0000 (UTC) Received: by mail-qk1-f202.google.com with SMTP id v143so4911393qka.21 for ; Fri, 18 Oct 2019 02:43:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=5sJ27FR/T7ltMjmEdKxnPYRQomCfdE3/RtdupJGc9Xw=; b=M1OHTJFs+TZpQ19jfDEAmHPoTbxVEF+/eF74bWLnxpDUcAqRT+sBul+V3jnyqrTZqk RauYRUDnMBALHzWc5grRJ2RA4ZVbGoVebmr2vsvUVDUx67VF1Ob5O7FKbBOkoQ3Yz5fV vmoGOPuaFJEY4lOkWMRNcd1bX+VgVPgwRb/ehjwdxqr3ndaEZS89wXfwYVIwqUfTzDEP EcHZgq35GaIfXl6AM3kF20q9B1CvDT0q4QJcZEtCl7JG16nX8gTS8Nut7iHTX7B275Ho ufgJ3rEMCfWPzzmYqL1m18q6nyTxKxj6KwXQoDB7qQfiqqJa9nv9wO2oE8Ut01YbS8ah KdPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=5sJ27FR/T7ltMjmEdKxnPYRQomCfdE3/RtdupJGc9Xw=; b=E1ZdgRcvISxvkQzk3xAPi1qGelL+hM9JkvUjGhkqUp334autaR8frFI2C+qqFD/tAb vLErik9SY/OmhDq3+4kaz+MGTnRX910QzWGP80MTgs6ot/PpC6TeKIIrlU+iVM0c6h40 LnH/GzpV8SOoDdIQrVo4TSO2UdPjuEE/khUm8O8CLu8siQ/zPGy5pVwGQAwSg7HPTInF HANxSzxSgyBglkwKIFrMs0rnZ04S0knl2twfjqn1dAePLa80XYf8erPu/jsB9mdL+3Zq Bdx/v2JrCtlRTW4kqoHtnyK8BR8S3h1Ue7NMsS9B+N3/auV+QUxn+k8I0r3Qluglg/7H qYDw== X-Gm-Message-State: APjAAAXj8rRGrulPAc/XKUU3SWT+z2ainNY0yyxYCXbelZv6jeRzRcFT BkMG6NrZ8U0HefI46e84mZBAWwMgDgE= X-Google-Smtp-Source: APXvYqyavxHEp1nzbSg6Ww9DlPfuLJHY0wvX/cPVxTvlVuC/U/WnhHWLdFAe0N6I+KNl8mE/kPDX71PoUHw= X-Received: by 2002:ac8:47c7:: with SMTP id d7mr9020364qtr.29.1571391811179; Fri, 18 Oct 2019 02:43:31 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:44 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-7-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 06/26] kasan: compiler.h: rename __no_kasan_or_inline into __no_memory_tool_or_inline From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Martin Schwidefsky , Andrey Ryabinin , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: As we use it for KMSAN as well now, let's change the name to be more generic. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Martin Schwidefsky Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Note that __no_kasan_or_inline is currently used only on S390, and KMSAN patches don't introduce uses of __no_memory_tool_or_inline, so this patch can be landed later if needed. Change-Id: I842d88b841bf1c75ab659b0016a808c6dcf7cdae --- arch/s390/include/asm/processor.h | 4 ++-- include/linux/compiler.h | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 51a0e4a2dc96..6bee92331fcd 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -214,7 +214,7 @@ static inline unsigned long current_stack_pointer(void) return sp; } -static __no_kasan_or_inline unsigned short stap(void) +static __no_memory_tool_or_inline unsigned short stap(void) { unsigned short cpu_address; @@ -253,7 +253,7 @@ static inline void __load_psw(psw_t psw) * Set PSW mask to specified value, while leaving the * PSW addr pointing to the next instruction. */ -static __no_kasan_or_inline void __load_psw_mask(unsigned long mask) +static __no_memory_tool_or_inline void __load_psw_mask(unsigned long mask) { unsigned long addr; psw_t psw; diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 5e88e7e33abe..4a594bd1bc47 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -199,19 +199,21 @@ void __read_once_size(const volatile void *p, void *res, int size) __READ_ONCE_SIZE; } -#ifdef CONFIG_KASAN +#if defined(CONFIG_KASAN) /* * We can't declare function 'inline' because __no_sanitize_address confilcts * with inlining. Attempt to inline it may cause a build failure. * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 * '__maybe_unused' allows us to avoid defined-but-not-used warnings. */ -# define __no_kasan_or_inline __no_sanitize_address notrace __maybe_unused +# define __no_memory_tool_or_inline __no_sanitize_address notrace __maybe_unused +#elif defined(CONFIG_KMSAN) +# define __no_memory_tool_or_inline __no_sanitize_memory notrace __maybe_unused #else -# define __no_kasan_or_inline __always_inline +# define __no_memory_tool_or_inline __always_inline #endif -static __no_kasan_or_inline +static __no_memory_tool_or_inline void __read_once_size_nocheck(const volatile void *p, void *res, int size) { __READ_ONCE_SIZE; @@ -274,7 +276,7 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s */ #define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0) -static __no_kasan_or_inline +static __no_memory_tool_or_inline unsigned long read_word_at_a_time(const void *addr) { kasan_check_read(addr, 1); From patchwork Fri Oct 18 09:42:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197979 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9E25514ED for ; Fri, 18 Oct 2019 09:43:38 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 50409222C6 for ; Fri, 18 Oct 2019 09:43:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="fen+QZJo" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 50409222C6 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id DFC678E0022; Fri, 18 Oct 2019 05:43:36 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id D849A8E0003; Fri, 18 Oct 2019 05:43:36 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id BFD268E0022; Fri, 18 Oct 2019 05:43:36 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0143.hostedemail.com [216.40.44.143]) by kanga.kvack.org (Postfix) with ESMTP id 979648E0003 for ; Fri, 18 Oct 2019 05:43:36 -0400 (EDT) Received: from smtpin15.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with SMTP id 2AA19181E7268 for ; Fri, 18 Oct 2019 09:43:36 +0000 (UTC) X-FDA: 76056418032.15.burn04_76a6f2519ff01 X-Spam-Summary: 50,0,0,da1853dce7c23e03,d41d8cd98f00b204,3rompxqykcpezebwxkzhhzex.vhfebgnq-ffdotvd.hkz@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:69:152:327:355:379:541:800:960:966:967:968:973:982:988:989:1260:1263:1277:1313:1314:1345:1359:1437:1516:1518:1593:1594:1605:1730:1747:1777:1792:2196:2198:2199:2200:2393:2525:2553:2565:2682:2685:2693:2731:2740:2859:2901:2904:2933:2937:2939:2942:2945:2947:2951:2954:3022:3138:3139:3140:3141:3142:3152:3743:3865:3866:3867:3868:3870:3871:3872:3873:3874:3934:3936:3938:3941:3944:3947:3950:3953:3956:3959:4250:4321:4385:4559:4605:5007:6117:6119:6120:6261:6653:6671:6755:7901:7903:7904:8599:8603:8660:8957:9025:9040:9163:9388:9969:10004:10954:11026:11232:11257:11473:11658:11914:12043:12219:12291:12296:12297:12438:12555:12683:12740:12776:12895:12986:13007:13146:13148:13230:13846:13972:14394:14651:14659:21063:21080:21222:21324:21365:21433:21444:21451:21611:21627:21740:21795:21796:30 003:3001 X-HE-Tag: burn04_76a6f2519ff01 X-Filterd-Recvd-Size: 20692 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf32.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:35 +0000 (UTC) Received: by mail-wr1-f73.google.com with SMTP id t11so2341839wro.10 for ; Fri, 18 Oct 2019 02:43:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=sz7bzilhVrL7w1odis6GBSZdGZcf4pty/YGaqav5Yfw=; b=fen+QZJoO5YDHHGclMUtOWpkDN9NCvPxijjCYXV+oHy9Uq5dL8faZM350hbdvyixxN TODV27X8YxhTUcWvz6KX3OJcE1jCkR0A1LQlHYZYlHPc++jM+4Rqh6rYEV0B1ZiCDfD+ Jwi91ZQY9As+FGjjFZm9IRsOq1CiZ7BQ6ctRtkwscykUwBWkz1W9zifdT+o/m+g9D+Ep eyEFpPL4RZNkLcvACaznThMbSDb/cFeEpwgy3tCpw3UQm3BkOOpBPQ3DS7TIvAgbZYVQ hLVaU6MKhZrUhdWXliHBC6A455ATGrY2qVVKyQFKa2TnBOyY75XkgB5VTYZBPcHsjwUy LMCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=sz7bzilhVrL7w1odis6GBSZdGZcf4pty/YGaqav5Yfw=; b=h9UIXbY4Jlr6b56nbQ5ki11A2sZUarTE7VPjs44nDTFTqGRMs0pzhpgwQz+YGzVvAw sJZmCm5Ku1I51voUxulX9YugBX+6Kgh23rrzMNqaAPPOVIsjsfetlgR1Rzyu7H/e3IDs ORhFa9nw8hRIQRBjRkxzzp0bZACvO3JfKKGYCYz1OISAbD2ovMTJOjh7PWwvjrSlrDG5 AbNXRnEuD8q1XLG/TC8gOXvZIjIjnUvGMRavdOz46wKvMGSwz187/4ColqLsX9U54t7x PmRwfeHr/+QeOWOuMADMnKxDULrd7dTk7Hxa3z+IOXLSgZDer37wZLvMkn2ChmmmBBgW SbUw== X-Gm-Message-State: APjAAAXS8+IgaydpORkBUu/JSqtptvP16VtXVO5ivnupY0AiCnQj4oAC oai9kdh1J6t+Jb+1iwSysrqm4f/C6Ao= X-Google-Smtp-Source: APXvYqyanVzbbMCp2GbsSoGU1HL5FZXe45segUfKa5EhqH/chN+b/7UCICsmRvJwOIpV6IFeL5ikeDvDRN0= X-Received: by 2002:adf:e74b:: with SMTP id c11mr6727221wrn.250.1571391814061; Fri, 18 Oct 2019 02:43:34 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:45 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-8-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 07/26] kmsan: add ReST documentation From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Add Documentation/dev-tools/kmsan.rst and reference it in the dev-tools index. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: Iac6345065e6804ef811f1124fdf779c67ff1530e --- Documentation/dev-tools/index.rst | 1 + Documentation/dev-tools/kmsan.rst | 418 ++++++++++++++++++++++++++++++ 2 files changed, 419 insertions(+) create mode 100644 Documentation/dev-tools/kmsan.rst diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/index.rst index b0522a4dd107..bc5e3fd87efa 100644 --- a/Documentation/dev-tools/index.rst +++ b/Documentation/dev-tools/index.rst @@ -19,6 +19,7 @@ whole; patches welcome! kcov gcov kasan + kmsan ubsan kmemleak gdb-kernel-debugging diff --git a/Documentation/dev-tools/kmsan.rst b/Documentation/dev-tools/kmsan.rst new file mode 100644 index 000000000000..51f9c207cc2c --- /dev/null +++ b/Documentation/dev-tools/kmsan.rst @@ -0,0 +1,418 @@ +============================= +KernelMemorySanitizer (KMSAN) +============================= + +KMSAN is a dynamic memory error detector aimed at finding uses of uninitialized +memory. +It is based on compiler instrumentation, and is quite similar to the userspace +MemorySanitizer tool (http://clang.llvm.org/docs/MemorySanitizer.html). + +KMSAN and Clang +=============== + +In order for KMSAN to work the kernel must be +built with Clang, which is so far the only compiler that has KMSAN support. +The kernel instrumentation pass is based on the userspace MemorySanitizer tool +(http://clang.llvm.org/docs/MemorySanitizer.html). Because of the +instrumentation complexity it's unlikely that any other compiler will support +KMSAN soon. + +Right now the instrumentation pass supports x86_64 only. + +How to build +============ + +In order to build a kernel with KMSAN you'll need a fresh Clang (10.0.0+, trunk +version r365008 or greater). Please refer to +https://llvm.org/docs/GettingStarted.html for the instructions on how to build +Clang:: + + export KMSAN_CLANG_PATH=/path/to/clang + # Now configure and build the kernel with CONFIG_KMSAN enabled. + make CC=$KMSAN_CLANG_PATH -j64 + +How KMSAN works +=============== + +KMSAN shadow memory +------------------- + +KMSAN associates a so-called shadow byte with every byte of kernel memory. +A bit in the shadow byte is set iff the corresponding bit of the kernel memory +byte is uninitialized. +Marking the memory uninitialized (i.e. setting its shadow bytes to 0xff) is +called poisoning, marking it initialized (setting the shadow bytes to 0x00) is +called unpoisoning. + +When a new variable is allocated on the stack, it's poisoned by default by +instrumentation code inserted by the compiler (unless it's a stack variable that +is immediately initialized). Any new heap allocation done without ``__GFP_ZERO`` +is also poisoned. + +Compiler instrumentation also tracks the shadow values with the help from the +runtime library in ``mm/kmsan/``. + +The shadow value of a basic or compound type is an array of bytes of the same +length. +When a constant value is written into memory, that memory is unpoisoned. +When a value is read from memory, its shadow memory is also obtained and +propagated into all the operations which use that value. For every instruction +that takes one or more values the compiler generates code that calculates the +shadow of the result depending on those values and their shadows. + +Example:: + + int a = 0xff; + int b; + int c = a | b; + +In this case the shadow of ``a`` is ``0``, shadow of ``b`` is ``0xffffffff``, +shadow of ``c`` is ``0xffffff00``. This means that the upper three bytes of +``c`` are uninitialized, while the lower byte is initialized. + + +Origin tracking +--------------- + +Every four bytes of kernel memory also have a so-called origin assigned to +them. +This origin describes the point in program execution at which the uninitialized +value was created. Every origin is associated with a creation stack, which lets +the user figure out what's going on. + +When an uninitialized variable is allocated on stack or heap, a new origin +value is created, and that variable's origin is filled with that value. +When a value is read from memory, its origin is also read and kept together +with the shadow. For every instruction that takes one or more values the origin +of the result is one of the origins corresponding to any of the uninitialized +inputs. +If a poisoned value is written into memory, its origin is written to the +corresponding storage as well. + +Example 1:: + + int a = 0; + int b; + int c = a + b; + +In this case the origin of ``b`` is generated upon function entry, and is +stored to the origin of ``c`` right before the addition result is written into +memory. + +Several variables may share the same origin address, if they are stored in the +same four-byte chunk. +In this case every write to either variable updates the origin for all of them. + +Example 2:: + + int combine(short a, short b) { + union ret_t { + int i; + short s[2]; + } ret; + ret.s[0] = a; + ret.s[1] = b; + return ret.i; + } + +If ``a`` is initialized and ``b`` is not, the shadow of the result would be +0xffff0000, and the origin of the result would be the origin of ``b``. +``ret.s[0]`` would have the same origin, but it will be never used, because +that variable is initialized. + +If both function arguments are uninitialized, only the origin of the second +argument is preserved. + +Origin chaining +~~~~~~~~~~~~~~~ +To ease the debugging, KMSAN creates a new origin for every memory store. +The new origin references both its creation stack and the previous origin the +memory location had. +This may cause increased memory consumption, so we limit the length of origin +chains in the runtime. + +Clang instrumentation API +------------------------- + +Clang instrumentation pass inserts calls to functions defined in +``mm/kmsan/kmsan_instr.c`` into the kernel code. + +Shadow manipulation +~~~~~~~~~~~~~~~~~~~ +For every memory access the compiler emits a call to a function that returns a +pair of pointers to the shadow and origin addresses of the given memory:: + + typedef struct { + void *s, *o; + } shadow_origin_ptr_t + + shadow_origin_ptr_t __msan_metadata_ptr_for_load_{1,2,4,8}(void *addr) + shadow_origin_ptr_t __msan_metadata_ptr_for_store_{1,2,4,8}(void *addr) + shadow_origin_ptr_t __msan_metadata_ptr_for_load_n(void *addr, u64 size) + shadow_origin_ptr_t __msan_metadata_ptr_for_store_n(void *addr, u64 size) + +The function name depends on the memory access size. +Each such function also checks if the shadow of the memory in the range +[``addr``, ``addr + n``) is contiguous and reports an error otherwise. + +The compiler makes sure that for every loaded value its shadow and origin +values are read from memory. +When a value is stored to memory, its shadow and origin are also stored using +the metadata pointers. + +Origin tracking +~~~~~~~~~~~~~~~ +A special function is used to create a new origin value for a local variable +and set the origin of that variable to that value:: + + void __msan_poison_alloca(u64 address, u64 size, char *descr) + +Access to per-task data +~~~~~~~~~~~~~~~~~~~~~~~~~ + +At the beginning of every instrumented function KMSAN inserts a call to +``__msan_get_context_state()``:: + + kmsan_context_state *__msan_get_context_state(void) + +``kmsan_context_state`` is declared in ``include/linux/kmsan.h``:: + + struct kmsan_context_s { + char param_tls[KMSAN_PARAM_SIZE]; + char retval_tls[RETVAL_SIZE]; + char va_arg_tls[KMSAN_PARAM_SIZE]; + char va_arg_origin_tls[KMSAN_PARAM_SIZE]; + u64 va_arg_overflow_size_tls; + depot_stack_handle_t param_origin_tls[PARAM_ARRAY_SIZE]; + depot_stack_handle_t retval_origin_tls; + depot_stack_handle_t origin_tls; + }; + +This structure is used by KMSAN to pass parameter shadows and origins between +instrumented functions. + +String functions +~~~~~~~~~~~~~~~~ + +The compiler replaces calls to ``memcpy()``/``memmove()``/``memset()`` with the +following functions. These functions are also called when data structures are +initialized or copied, making sure shadow and origin values are copied alongside +with the data:: + + void *__msan_memcpy(void *dst, void *src, u64 n) + void *__msan_memmove(void *dst, void *src, u64 n) + void *__msan_memset(void *dst, int c, size_t n) + +Error reporting +~~~~~~~~~~~~~~~ + +For each pointer dereference and each condition the compiler emits a shadow +check that calls ``__msan_warning()`` in the case a poisoned value is being +used:: + + void __msan_warning(u32 origin) + +``__msan_warning()`` causes KMSAN runtime to print an error report. + +Inline assembly instrumentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +KMSAN instruments every inline assembly output with a call to:: + + void __msan_instrument_asm_store(u64 addr, u64 size) + +, which unpoisons the memory region. + +This approach may mask certain errors, but it also helps to avoid a lot of +false positives in bitwise operations, atomics etc. + +Sometimes the pointers passed into inline assembly don't point to valid memory. +In such cases they are ignored at runtime. + +Disabling the instrumentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A function can be marked with ``__no_sanitize_memory``. +Doing so doesn't remove KMSAN instrumentation from it, however it makes the +compiler ignore the uninitialized values coming from the function's inputs, +and initialize the function's outputs. +The compiler won't inline functions marked with this attribute into functions +not marked with it, and vice versa. + +It's also possible to disable KMSAN for a single file (e.g. main.o):: + + KMSAN_SANITIZE_main.o := n + +or for the whole directory:: + + KMSAN_SANITIZE := n + +in the Makefile. This comes at a cost however: stack allocations from such files +and parameters of instrumented functions called from them will have incorrect +shadow/origin values. As a rule of thumb, avoid using KMSAN_SANITIZE. + +Runtime library +--------------- +The code is located in ``mm/kmsan/``. + +Per-task KMSAN state +~~~~~~~~~~~~~~~~~~~~ + +Every task_struct has an associated KMSAN task state that holds the KMSAN +context (see above) and a per-task flag disallowing KMSAN reports:: + + struct kmsan_task_state { + ... + bool allow_reporting; + struct kmsan_context_state cstate; + ... + } + + struct task_struct { + ... + struct kmsan_task_state kmsan; + ... + } + + +KMSAN contexts +~~~~~~~~~~~~~~ + +When running in a kernel task context, KMSAN uses ``current->kmsan.cstate`` to +hold the metadata for function parameters and return values. + +But in the case the kernel is running in the interrupt, softirq or NMI context, +where ``current`` is unavailable, KMSAN switches to per-cpu interrupt state:: + + DEFINE_PER_CPU(kmsan_context_state[KMSAN_NESTED_CONTEXT_MAX], + kmsan_percpu_cstate); + +Metadata allocation +~~~~~~~~~~~~~~~~~~~ +There are several places in the kernel for which the metadata is stored. + +1. Each ``struct page`` instance contains two pointers to its shadow and +origin pages:: + + struct page { + ... + struct page *shadow, *origin; + ... + }; + +Every time a ``struct page`` is allocated, the runtime library allocates two +additional pages to hold its shadow and origins. This is done by adding hooks +to ``alloc_pages()``/``free_pages()`` in ``mm/page_alloc.c``. +To avoid allocating the metadata for non-interesting pages (right now only the +shadow/origin page themselves and stackdepot storage) the +``__GFP_NO_KMSAN_SHADOW`` flag is used. + +There is a problem related to this allocation algorithm: when two contiguous +memory blocks are allocated with two different ``alloc_pages()`` calls, their +shadow pages may not be contiguous. So, if a memory access crosses the boundary +of a memory block, accesses to shadow/origin memory may potentially corrupt +other pages or read incorrect values from them. + +As a workaround, we check the access size in +``__msan_metadata_ptr_for_XXX_YYY()`` and return a pointer to a fake shadow +region in the case of an error:: + + char dummy_load_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); + char dummy_store_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); + +``dummy_load_page`` is zero-initialized, so reads from it always yield zeroes. +All stores to ``dummy_store_page`` are ignored. + +Unfortunately at boot time we need to allocate shadow and origin pages for the +kernel data (``.data``, ``.bss`` etc.) and percpu memory regions, the size of +which is not a power of 2. As a result, we have to allocate the metadata page by +page, so that it is also non-contiguous, although it may be perfectly valid to +access the corresponding kernel memory across page boundaries. +This can be probably fixed by allocating 1<] __dump_stack lib/dump_stack.c:15 + [] dump_stack+0x238/0x290 lib/dump_stack.c:51 + [] kmsan_report+0x276/0x2e0 mm/kmsan/kmsan.c:1003 + [] __msan_warning+0x5b/0xb0 mm/kmsan/kmsan_instr.c:424 + [< inline >] strlen lib/string.c:484 + [] strlcpy+0x9d/0x200 lib/string.c:144 + [] packet_bind_spkt+0x144/0x230 net/packet/af_packet.c:3132 + [] SYSC_bind+0x40d/0x5f0 net/socket.c:1370 + [] SyS_bind+0x82/0xa0 net/socket.c:1356 + [] entry_SYSCALL_64_fastpath+0x13/0x8f arch/x86/entry/entry_64.o:? + chained origin: + [] save_stack_trace+0x27/0x50 arch/x86/kernel/stacktrace.c:67 + [< inline >] kmsan_save_stack_with_flags mm/kmsan/kmsan.c:322 + [< inline >] kmsan_save_stack mm/kmsan/kmsan.c:334 + [] kmsan_internal_chain_origin+0x118/0x1e0 mm/kmsan/kmsan.c:527 + [] __msan_set_alloca_origin4+0xc3/0x130 mm/kmsan/kmsan_instr.c:380 + [] SYSC_bind+0x129/0x5f0 net/socket.c:1356 + [] SyS_bind+0x82/0xa0 net/socket.c:1356 + [] entry_SYSCALL_64_fastpath+0x13/0x8f arch/x86/entry/entry_64.o:? + origin description: ----address@SYSC_bind (origin=00000000eb400911) + ================================================================== + +The report tells that the local variable ``address`` was created uninitialized +in ``SYSC_bind()`` (the ``bind`` system call implementation). The lower stack +trace corresponds to the place where this variable was created. + +The upper stack shows where the uninit value was used - in ``strlen()``. +It turned out that the contents of ``address`` were partially copied from the +userspace, but the buffer wasn't zero-terminated and contained some trailing +uninitialized bytes. +``packet_bind_spkt()`` didn't check the length of the buffer, but called +``strlcpy()`` on it, which called ``strlen()``, which started reading the +buffer byte by byte till it hit the uninitialized memory. + + +References +========== + +E. Stepanov, K. Serebryany. MemorySanitizer: fast detector of uninitialized +memory use in C++. +In Proceedings of CGO 2015. From patchwork Fri Oct 18 09:42:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197981 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5D2C913B1 for ; Fri, 18 Oct 2019 09:43:41 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 20D2520820 for ; Fri, 18 Oct 2019 09:43:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="foQBOT+r" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 20D2520820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 373F88E0023; Fri, 18 Oct 2019 05:43:39 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 2FCC98E0003; Fri, 18 Oct 2019 05:43:39 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 213AB8E0023; Fri, 18 Oct 2019 05:43:39 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0034.hostedemail.com [216.40.44.34]) by kanga.kvack.org (Postfix) with ESMTP id F04438E0003 for ; Fri, 18 Oct 2019 05:43:38 -0400 (EDT) Received: from smtpin13.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with SMTP id 7A0278277BED for ; Fri, 18 Oct 2019 09:43:38 +0000 (UTC) X-FDA: 76056418116.13.fact92_770e06ca9e854 X-Spam-Summary: 2,0,0,a7c49aa4a5f74068,d41d8cd98f00b204,3simpxqykcpmbgdyzmbjjbgz.xjhgdips-hhfqvxf.jmb@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:akpm@linux-foundation.org:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:2393:2553:2559:2562:3138:3139:3140:3141:3142:3152:3352:3865:3867:3868:3871:3874:4250:4321:5007:6119:6120:6261:6653:7901:7903:7904:9969:10004:10400:11026:11232:11473:11658:11914:12043:12297:12438:12555:12895:13069:13311:13357:13846:14096:14097:14181:14394:14659:14721:21080:21365:21433:21444:21451:21627:30054:30064:30090,0,RBL:209.85.128.74:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: fact92_770e06ca9e854 X-Filterd-Recvd-Size: 4393 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf37.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:37 +0000 (UTC) Received: by mail-wm1-f74.google.com with SMTP id v26so364956wmh.2 for ; Fri, 18 Oct 2019 02:43:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Fq1aR6bk0bOUK9AfN6hxl7otJcG65B93WABxCwJyYAU=; b=foQBOT+r+tvtFJQdtLJM7hHIJC9CEZwProhyezQxi0mPc4Ts1zdsgj62S+tSdIT3Go Zow1l3rX6q0UI26hEGvc2v10LPwxIn2JFlaaD/4n81KMts5bYn/JOLa/IH4uZWoYQf3V 0KUDZ4nIHiXTxkIa6WANJYaRfk0E3ibRxP1jWRupjH1/7qrr5oBAIgfH8TlH4WfUMihA fbUmIqHndri27r34k680cyGg026vieL8YIZnltaDCQnK7kDdc+gNQ9UZB+vjlZGRvUmq CAEC+E7WProy36BPpAvBY9nSkbnfOHNj4G3Rt3zdzxNukcent5IP4T5SituWJawtCO4y bmBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Fq1aR6bk0bOUK9AfN6hxl7otJcG65B93WABxCwJyYAU=; b=O1MaUudDjljQPxo2ZsbKfAKuvqh+pPvJzttfmXHLszSVVCLiOZ7f+i8mPDLdSa0yUC UxuamsGHncpR8GgLcL1QbMXTiVKhfnkU18kyCAByNp5HPSMyoIsRtkl0lESlNVaVbFXZ k630emik1d15wten9o8HzafhI0oPNbe0ARiT0UG3DYD57AXR2yO2herSJDXITrLtuOd8 fPG9bjE3/uOSdavZuSam1UwgHOJEpisC2ZTsxYwDIKAO+cIAl3w988Xiv8sIjwEE6i5i M+eQ0icGN4rUBXEs3wb5Uf6pTmp3kuYkJPMuHj37SjAprb4bItpMj2tObsv9hqbKYkb8 08FA== X-Gm-Message-State: APjAAAVF7yaB4TPG7jOJla5bx71xEG+kEJ7VSW9GOFsUt1d4B+/RvJmU VFO7PCBmKSIEaPgMx4+PshQKc1zEskI= X-Google-Smtp-Source: APXvYqwqmQbdcaEtuC6Tdfd2oIHdTU1EQ9xvJORBBqGBrZL5scw397C+KzjGjfJOMwLMNSnbMK/RvbNZ0CA= X-Received: by 2002:adf:fc10:: with SMTP id i16mr6689092wrr.157.1571391816882; Fri, 18 Oct 2019 02:43:36 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:46 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-9-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 08/26] kmsan: gfp: introduce __GFP_NO_KMSAN_SHADOW From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Andrew Morton , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This flag is to be used by KMSAN runtime to mark that newly created memory pages don't need KMSAN metadata backing them. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Andrew Morton Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- We can't decide what to do here: - do we need to conditionally define ___GFP_NO_KMSAN_SHADOW depending on CONFIG_KMSAN like LOCKDEP does? - if KMSAN is defined, and LOCKDEP is not, do we want to "compactify" the GFP bits? Change-Id: If5d0352fd5711ad103328e2c185eb885e826423a --- include/linux/gfp.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index fb07b503dc45..b4e7963cd94b 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -44,6 +44,7 @@ struct vm_area_struct; #else #define ___GFP_NOLOCKDEP 0 #endif +#define ___GFP_NO_KMSAN_SHADOW 0x1000000u /* If the above are modified, __GFP_BITS_SHIFT may need updating */ /* @@ -212,12 +213,13 @@ struct vm_area_struct; #define __GFP_NOWARN ((__force gfp_t)___GFP_NOWARN) #define __GFP_COMP ((__force gfp_t)___GFP_COMP) #define __GFP_ZERO ((__force gfp_t)___GFP_ZERO) +#define __GFP_NO_KMSAN_SHADOW ((__force gfp_t)___GFP_NO_KMSAN_SHADOW) /* Disable lockdep for GFP context tracking */ #define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP) /* Room for N __GFP_FOO bits */ -#define __GFP_BITS_SHIFT (23 + IS_ENABLED(CONFIG_LOCKDEP)) +#define __GFP_BITS_SHIFT (25) #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /** From patchwork Fri Oct 18 09:42:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197983 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 54F1313B1 for ; Fri, 18 Oct 2019 09:43:44 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 2264220820 for ; Fri, 18 Oct 2019 09:43:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Xbn4iZEx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2264220820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 28A168E0024; Fri, 18 Oct 2019 05:43:42 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 2165B8E0003; Fri, 18 Oct 2019 05:43:42 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 129458E0024; Fri, 18 Oct 2019 05:43:42 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0139.hostedemail.com [216.40.44.139]) by kanga.kvack.org (Postfix) with ESMTP id E04DD8E0003 for ; Fri, 18 Oct 2019 05:43:41 -0400 (EDT) Received: from smtpin04.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with SMTP id 50DA318209A86 for ; Fri, 18 Oct 2019 09:43:41 +0000 (UTC) X-FDA: 76056418242.04.nest14_777656dd97c03 X-Spam-Summary: 2,0,0,0924994ee39413bc,d41d8cd98f00b204,3s4mpxqykcpyejgbcpemmejc.amkjglsv-kkityai.mpe@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:1981:2194:2199:2393:2559:2562:3138:3139:3140:3141:3142:3152:3353:3865:3866:3867:3868:3871:3872:3874:4250:4321:5007:6119:6120:6261:6653:7901:9969:10004:10400:11026:11232:11473:11658:11914:12043:12296:12297:12438:12555:12895:13069:13255:13311:13357:13846:14096:14097:14181:14394:14659:14721:21080:21365:21444:21451:21627:30054:30064,0,RBL:209.85.221.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.175.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:30,LUA_SUMMARY:none X-HE-Tag: nest14_777656dd97c03 X-Filterd-Recvd-Size: 4572 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf28.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:40 +0000 (UTC) Received: by mail-wr1-f73.google.com with SMTP id v7so414908wrf.4 for ; Fri, 18 Oct 2019 02:43:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ykyUG9wjmMVlXZORIhUUUfbyzYBAOpIbtAYdLbQkt+k=; b=Xbn4iZEx2VhJhkoif/O5VzwdOh4wzkpmFcQOAtTaE3gbLTDkBwwCIXEJJCX+qd/rel LhBYj+qOugf2XFQTFsr1pX4xFuXVV2Uid9YvIA6kIMMx8ZJosB6xvBsL0Y/b33Wlzarb A2hb6GPyDGMD1JbbIFMT6kTTJCoSIfQxcoF76K3aww9aGQSz0AvLdgSFJZdYDLkU0YSn I1kC4AQkjZhChlV3lbEA3YAcU2qBkVmzFgpTYI+ry7Jx6HL+SdccwQrQvdC1zlG2F69t yLUeSArdjQgjiY7uC2mX8yDQT4QahifIYTdShm/l/lY9BAoP9yxoewDdswETvHWbJLmr UcAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ykyUG9wjmMVlXZORIhUUUfbyzYBAOpIbtAYdLbQkt+k=; b=rSqOPxGg4WPL1/WgemD9Bpk93Ks+dfMWAjKxdytmGeQommspbnXoGOcDlFlprVhQ7M 310AH1vZGxPjiKWd7T7F1EPdP/tB1C94KsmV6NPCOyQnEVeVdAncfkc7tgHuSoj+9ldP C272RLkX5aZNzwB3kOBdCghKU0GPGCzfVWNHhJl2M83qrTvF6KgDxSk5x8R+OxtBVZHP Z5hk5otyVwXfHYqcpIeoDMlKE/lXX2P74hi6QJ8pJ//Q0biOgSBqozQDBO4T1wb3tfPc Rk/zTuGbbQqkVVtcrgCSR5APrY+IzdTA6tfEpBvkNsAHtfvoG4NGAzjrAxsCPVI7jT9A dYIw== X-Gm-Message-State: APjAAAXDhHZ7pNhBwuBLe6ic6Q8JzLhDJK851cBicTk+GrZXx3SXdHIx 6WQ8YGq1+AW0Of6IG4h7ijEdOKlWoi0= X-Google-Smtp-Source: APXvYqyrkg8N0d8HRk2q40QlbsncMGiZ0Q5WEQRsdEynfiNi2jU4mq8U4SG6zmgYpVpKQmLNE/PhxAfkxnM= X-Received: by 2002:adf:e982:: with SMTP id h2mr4629886wrm.53.1571391819716; Fri, 18 Oct 2019 02:43:39 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:47 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-10-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 09/26] kmsan: introduce __no_sanitize_memory and __SANITIZE_MEMORY__ From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: __no_sanitize_memory is a function attribute that makes KMSAN ignore the uninitialized values coming from the function's inputs, and initialize the function's outputs. Functions marked with this attribute can't be inlined into functions not marked with it, and vice versa. __SANITIZE_MEMORY__ is a macro that's defined iff the file is instrumented with KMSAN. This is not the same as CONFIG_KMSAN, which is defined for every file. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I1f1672652c8392f15f7ca8ac26cd4e71f9cc1e4b --- include/linux/compiler-clang.h | 8 ++++++++ include/linux/compiler-gcc.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index 333a6695a918..edba13a069a6 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -24,6 +24,14 @@ #define __no_sanitize_address #endif +/* KMSAN is a Clang-only tool, thus putting the defines here */ +#if __has_feature(memory_sanitizer) +# define __SANITIZE_MEMORY__ +# define __no_sanitize_memory __attribute__((no_sanitize("kernel-memory"))) +#else +# define __no_sanitize_memory +#endif + /* * Not all versions of clang implement the the type-generic versions * of the builtin overflow checkers. Fortunately, clang implements diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index d7ee4c6bad48..e5ebc788dde4 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -145,6 +145,11 @@ #define __no_sanitize_address #endif +/* + * GCC doesn't support KMSAN. + */ +#define __no_sanitize_memory + #if GCC_VERSION >= 50100 #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 #endif From patchwork Fri Oct 18 09:42:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197985 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 22BAD14ED for ; Fri, 18 Oct 2019 09:43:47 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id DE12220820 for ; Fri, 18 Oct 2019 09:43:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Uw11v+PW" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DE12220820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id E9A548E0025; Fri, 18 Oct 2019 05:43:44 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id DFA518E0003; Fri, 18 Oct 2019 05:43:44 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C73DF8E0025; Fri, 18 Oct 2019 05:43:44 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0182.hostedemail.com [216.40.44.182]) by kanga.kvack.org (Postfix) with ESMTP id A65498E0003 for ; Fri, 18 Oct 2019 05:43:44 -0400 (EDT) Received: from smtpin28.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with SMTP id 400F210EEE for ; Fri, 18 Oct 2019 09:43:44 +0000 (UTC) X-FDA: 76056418368.28.hot21_77e201e27bb57 X-Spam-Summary: 2,0,0,e2d9e36cc9d23bcc,d41d8cd98f00b204,3tompxqykcpkhmjefshpphmf.dpnmjovy-nnlwbdl.psh@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:akpm@linux-foundation.org:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:2393:2559:2562:3138:3139:3140:3141:3142:3152:3352:3865:3866:3867:3868:3870:3871:4250:4321:5007:6120:6261:6653:7901:9036:9969:10004:10400:11026:11232:11473:11657:11658:11914:12043:12296:12297:12438:12555:12895:12986:13069:13311:13357:13846:14096:14097:14181:14394:14659:14721:21080:21365:21444:21451:21627:30054:30064,0,RBL:209.85.128.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: hot21_77e201e27bb57 X-Filterd-Recvd-Size: 4501 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf17.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:43 +0000 (UTC) Received: by mail-wm1-f73.google.com with SMTP id z5so623013wma.5 for ; Fri, 18 Oct 2019 02:43:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=voMa8uMkO0bR++wyxPvNpVmAIPkUx6wSAyHVLN1gnqY=; b=Uw11v+PWXmwK/tlg4ihfCGzje2gofiJSgXAEdv/o1WZ02mRKczyGu2EhE4ll/Qx6ES GcgvS+RSYgAq6c+y/S0pIDMEZcqRuQW1g9zQRO2DcZnO0J4ZOt/oVoZHwVqLDcXjyJhF Bwxg59pRCYuYcYvyNikE9eul74jF/R9kEPTEOTbIPgTH62RAaMGNpLjanpT00X8lL7XD aP52AOZ7WmtFbbzGmo60ufp77C7hs/12piQ+PaVXvw5/bInkQMP0X1zCk7LkPcCKyfUs xeG6dtJrxXRBtRX2pa1ZSs2OCv98gcYJDPl4aEUQt0rABHsM4+UCbm0/I5MXCuL7Jdyy vV1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=voMa8uMkO0bR++wyxPvNpVmAIPkUx6wSAyHVLN1gnqY=; b=OcCdCdlDK8pfzFUKTg5hehjgy6blBa3odq7dnGBpgvHw+kZckK16LDOHM8dHW3EXWt YZksvqSPZqG2DmgKxKdcxwy55it7qcz+sl8o3mJPVK4KFl3AucMJmB+M8OS8dIhSX2by FOxmHSaGmaDaVoRlGjl4dro24MAI6+wYyt1vzIxUX1Ry1XeP6rYt+tNI343LybAXaceJ DmHS/+pyIb8TukyqZLgaEM7gqpZNnQqCRGlrR0xcZdsbRwGx2LAYUVhL3GkwqpR0sjQi dURlh/RNRnCywunMoJbtT7OjKfBP6TJQ2cszZM98W9z9xsBrb+BQlsJLzolaCuXfwOPz xvAA== X-Gm-Message-State: APjAAAUZeHPDRDEp/ciVC1yc86P55WZIfCBP2os02wnu+NxznYnm789U bmQIhvPX7Xr0rH1+S//ft2tVJGcMj9Q= X-Google-Smtp-Source: APXvYqxc792Cv1nihwKH6Y90JXoOasFlhLR4/84MHPVrtaPJ+9Oowbv8s2Rqrjmr1aiFvqFrEWyKVMBDozQ= X-Received: by 2002:a5d:4ed2:: with SMTP id s18mr2984564wrv.187.1571391822586; Fri, 18 Oct 2019 02:43:42 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:48 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-11-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 10/26] kmsan: reduce vmalloc space From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Andrew Morton , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: KMSAN is going to use 3/4 of existing vmalloc space to hold the metadata, therefore we lower VMALLOC_END to make sure vmalloc() doesn't allocate past the first 1/4. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Andrew Morton Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: Iaa5e8e0fc2aa66c956f937f5a1de6e5ef40d57cc --- arch/x86/include/asm/pgtable_64_types.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h index 52e5f5f2240d..586629e20436 100644 --- a/arch/x86/include/asm/pgtable_64_types.h +++ b/arch/x86/include/asm/pgtable_64_types.h @@ -139,7 +139,22 @@ extern unsigned int ptrs_per_p4d; # define VMEMMAP_START __VMEMMAP_BASE_L4 #endif /* CONFIG_DYNAMIC_MEMORY_LAYOUT */ +#ifndef CONFIG_KMSAN #define VMALLOC_END (VMALLOC_START + (VMALLOC_SIZE_TB << 40) - 1) +#else +/* + * In KMSAN builds vmalloc area is four times smaller, and the remaining 3/4 + * are used to keep the metadata for virtual pages. + */ +#define VMALLOC_QUARTER_SIZE ((VMALLOC_SIZE_TB << 40) >> 2) +#define VMALLOC_END (VMALLOC_START + VMALLOC_QUARTER_SIZE - 1) +#define VMALLOC_SHADOW_OFFSET VMALLOC_QUARTER_SIZE +#define VMALLOC_ORIGIN_OFFSET (VMALLOC_QUARTER_SIZE * 2) +#define VMALLOC_META_END (VMALLOC_END + VMALLOC_ORIGIN_OFFSET) +#define MODULES_SHADOW_START (VMALLOC_META_END + 1) +#define MODULES_ORIGIN_START (MODULES_SHADOW_START + MODULES_LEN) +#define MODULES_ORIGIN_END (MODULES_ORIGIN_START + MODULES_LEN) +#endif #define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE) /* The module sections ends with the start of the fixmap */ From patchwork Fri Oct 18 09:42:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197987 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EAB6614ED for ; Fri, 18 Oct 2019 09:43:51 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 759A920820 for ; Fri, 18 Oct 2019 09:43:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="C3GmBCWl" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 759A920820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 4ABC88E0026; Fri, 18 Oct 2019 05:43:49 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 4391E8E0003; Fri, 18 Oct 2019 05:43:49 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 260DC8E0026; Fri, 18 Oct 2019 05:43:49 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id D693B8E0003 for ; Fri, 18 Oct 2019 05:43:48 -0400 (EDT) Received: from smtpin23.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with SMTP id 74DBE1822BC76 for ; Fri, 18 Oct 2019 09:43:48 +0000 (UTC) X-FDA: 76056418536.23.care78_7854a49184c3d X-Spam-Summary: 2,0,0,c0a0eafde63a3308,d41d8cd98f00b204,3uympxqykcpwkpmhivksskpi.gsqpmry1-qqozego.svk@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:152:355:379:541:960:966:967:973:982:988:989:1042:1260:1277:1311:1313:1314:1345:1359:1431:1437:1513:1515:1516:1518:1521:1593:1594:1605:1730:1747:1777:1792:2194:2196:2198:2199:2200:2201:2393:2525:2538:2559:2563:2682:2685:2693:2731:2859:2897:2898:2901:2902:2904:2918:2924:2926:2933:2937:2939:2942:2945:2947:2951:2954:3022:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:3872:3873:3874:3934:3936:3938:3941:3944:3947:3950:3953:3956:3959:4250:4321:4385:4605:5007:6120:6261:6653:7875:7901:7903:7904:8603:8660:8784:8957:9025:9036:9108:9969:10004:11026:11232:11233:11657:11914:12043:12219:12291:12294:12295:12296:12297:12438:12555:12683:12895:12986:13141:13148:13149:13230:13846:13972:14394:14659:21080:21365:21433:21444:21451:21627:21772:21795:21796:21809:21939:30003:30012:3003 4:30036: X-HE-Tag: care78_7854a49184c3d X-Filterd-Recvd-Size: 90242 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf24.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:46 +0000 (UTC) Received: by mail-wm1-f74.google.com with SMTP id c188so2075173wmd.9 for ; Fri, 18 Oct 2019 02:43:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=6yB5qFFfos/YCtr5XsIWTq5HAdbR/ail3y2q+/X4j/E=; b=C3GmBCWlZT32zTFnkQvh0weiV+5i8TwFQ1d8C/qrAzSIeo1mJJh4nHTg7aoEYXnxzQ lwR0wpoDIqYereSSkS3ITRHtDrEG8QGex5g0RYGlfemhbiJoNlGX5oGnAzu3kUOZkL0J f8sn5xS8srZ3LfbQ4T2K4d5Ow8uu07kOX6eeRJkZep5fpvLisajZ3wH10Fx/fi+cTc05 /UDQjpY1r+ukzqu0blCma7kJhVjD6COq0AyQctGo0KLSgXMVhfE93cwzJOSb/MinZpwS WP/vi53X3BTNdcCy07k2SyiPmD+b0jjsFX90fTuWKrctXSEl4LDxFuqmcHkmTgrO4/es lVFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=6yB5qFFfos/YCtr5XsIWTq5HAdbR/ail3y2q+/X4j/E=; b=pOtvHIhtnTnd1NdCJBW/hPqNOH5bt7lAcR4JsEFKUpt7qBDI817Xw31o1eUejwSKdW lQI2dilC2c2BlIteBNampFR5aYtP/hGW0ZoyYPKScmbOF4o5fDEtIWxEExN/PAVrwNQz EwuW2ea924x2sJ+nI5TK1Qa09p6iPM7fQBFPxqrVPhXphKqS4OdK9a3CZdF4nViJPyA/ f9ghaRcun+klwww7/tSPN++v59m/ZlZn5OpQmge2QTCKt3q3ik/EcubS79gXezNAnfKr erNHNH0K/xCOW1CufstB0LB7sMnCFbqTF9BnmtXvviVxNPKrQh6mbpmf/h/4576RkMCd 2DOQ== X-Gm-Message-State: APjAAAWVAzcEWBBiKkMbSzVUd3NiUZA4s0X8GrwNBcsvW0q0pMoOQraV +TF3kTzDkI/+aGdZVXWMtnp14Io2OXI= X-Google-Smtp-Source: APXvYqybT5+csqMriUCdkttcL1+IwQMPsx1RBJmDzxg4sqK3/KByeG1N+9krG9AdT2eFX1UB2+EqtONt7VM= X-Received: by 2002:adf:8527:: with SMTP id 36mr6625295wrh.144.1571391825518; Fri, 18 Oct 2019 02:43:45 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:49 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-12-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 11/26] kmsan: add KMSAN runtime From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This patch adds the KernelMemorySanitizer runtime and associated files: - arch/x86/include/asm/kmsan.h: assembly definitions for hooking interrupt handlers; - include/linux/kmsan-checks.h: user API to enable/disable KMSAN, poison/unpoison memory etc. - include/linux/kmsan.h: declarations of KMSAN memory hooks to be referenced outside KMSAN runtime - lib/Kconfig.kmsan: declarations for CONFIG_KMSAN and CONFIG_TEST_KMSAN - mm/kmsan/Makefile: boilerplate Makefile - mm/kmsan/kmsan.h: internal KMSAN declarations - mm/kmsan/kmsan.c: core functions that operate with shadow and origin memory and perform checks, utility functions - mm/kmsan/kmsan_entry.c: KMSAN hooks for entry_64.S - mm/kmsan/kmsan_hooks.c: KMSAN hooks for kernel subsystems - mm/kmsan/kmsan_init.c: KMSAN initialization routines - mm/kmsan/kmsan_instr.c: functions called by KMSAN instrumentation - scripts/Makefile.kmsan: CFLAGS_KMSAN Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I4b3a7aba6d5804afac4f5f7274cadf8675b6e119 --- arch/x86/Kconfig | 1 + arch/x86/include/asm/kmsan.h | 129 ++++++++ include/linux/kmsan-checks.h | 123 ++++++++ include/linux/kmsan.h | 143 +++++++++ lib/Kconfig.debug | 2 + lib/Kconfig.kmsan | 22 ++ mm/kmsan/Makefile | 4 + mm/kmsan/kmsan.c | 570 +++++++++++++++++++++++++++++++++++ mm/kmsan/kmsan.h | 147 +++++++++ mm/kmsan/kmsan_entry.c | 130 ++++++++ mm/kmsan/kmsan_hooks.c | 416 +++++++++++++++++++++++++ mm/kmsan/kmsan_init.c | 88 ++++++ mm/kmsan/kmsan_instr.c | 259 ++++++++++++++++ mm/kmsan/kmsan_report.c | 135 +++++++++ mm/kmsan/kmsan_shadow.c | 543 +++++++++++++++++++++++++++++++++ mm/kmsan/kmsan_shadow.h | 30 ++ scripts/Makefile.kmsan | 12 + 17 files changed, 2754 insertions(+) create mode 100644 arch/x86/include/asm/kmsan.h create mode 100644 include/linux/kmsan-checks.h create mode 100644 include/linux/kmsan.h create mode 100644 lib/Kconfig.kmsan create mode 100644 mm/kmsan/Makefile create mode 100644 mm/kmsan/kmsan.c create mode 100644 mm/kmsan/kmsan.h create mode 100644 mm/kmsan/kmsan_entry.c create mode 100644 mm/kmsan/kmsan_hooks.c create mode 100644 mm/kmsan/kmsan_init.c create mode 100644 mm/kmsan/kmsan_instr.c create mode 100644 mm/kmsan/kmsan_report.c create mode 100644 mm/kmsan/kmsan_shadow.c create mode 100644 mm/kmsan/kmsan_shadow.h create mode 100644 scripts/Makefile.kmsan diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index d6e1faa28c58..3f83a5c53808 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -135,6 +135,7 @@ config X86 select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_JUMP_LABEL_RELATIVE select HAVE_ARCH_KASAN if X86_64 + select HAVE_ARCH_KMSAN if X86_64 select HAVE_ARCH_KGDB select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT diff --git a/arch/x86/include/asm/kmsan.h b/arch/x86/include/asm/kmsan.h new file mode 100644 index 000000000000..22322904102b --- /dev/null +++ b/arch/x86/include/asm/kmsan.h @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Assembly bits to safely invoke KMSAN hooks from .S files. + * + * Adopted from KTSAN assembly hooks implementation by Dmitry Vyukov: + * https://github.com/google/ktsan/blob/ktsan/arch/x86/include/asm/ktsan.h + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef _ASM_X86_KMSAN_H +#define _ASM_X86_KMSAN_H + +#ifdef CONFIG_KMSAN + +#define KMSAN_PUSH_REGS \ + pushq %rax; \ + pushq %rcx; \ + pushq %rdx; \ + pushq %rdi; \ + pushq %rsi; \ + pushq %r8; \ + pushq %r9; \ + pushq %r10; \ + pushq %r11; \ +/**/ + +#define KMSAN_POP_REGS \ + popq %r11; \ + popq %r10; \ + popq %r9; \ + popq %r8; \ + popq %rsi; \ + popq %rdi; \ + popq %rdx; \ + popq %rcx; \ + popq %rax; \ +/**/ + +#define KMSAN_INTERRUPT_ENTER \ + KMSAN_PUSH_REGS \ + call kmsan_interrupt_enter; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_INTERRUPT_EXIT \ + KMSAN_PUSH_REGS \ + call kmsan_interrupt_exit; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_SOFTIRQ_ENTER \ + KMSAN_PUSH_REGS \ + call kmsan_softirq_enter; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_SOFTIRQ_EXIT \ + KMSAN_PUSH_REGS \ + call kmsan_softirq_exit; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_NMI_ENTER \ + KMSAN_PUSH_REGS \ + call kmsan_nmi_enter; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_NMI_EXIT \ + KMSAN_PUSH_REGS \ + call kmsan_nmi_exit; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_SYSCALL_ENTER \ + KMSAN_PUSH_REGS \ + call kmsan_syscall_enter; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_SYSCALL_EXIT \ + KMSAN_PUSH_REGS \ + call kmsan_syscall_exit; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_IST_ENTER(shift_ist) \ + KMSAN_PUSH_REGS \ + movq $shift_ist, %rdi; \ + call kmsan_ist_enter; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_IST_EXIT(shift_ist) \ + KMSAN_PUSH_REGS \ + movq $shift_ist, %rdi; \ + call kmsan_ist_exit; \ + KMSAN_POP_REGS \ +/**/ + +#define KMSAN_UNPOISON_PT_REGS \ + KMSAN_PUSH_REGS \ + call kmsan_unpoison_pt_regs; \ + KMSAN_POP_REGS \ +/**/ + + +#else /* ifdef CONFIG_KMSAN */ + +#define KMSAN_INTERRUPT_ENTER +#define KMSAN_INTERRUPT_EXIT +#define KMSAN_SOFTIRQ_ENTER +#define KMSAN_SOFTIRQ_EXIT +#define KMSAN_NMI_ENTER +#define KMSAN_NMI_EXIT +#define KMSAN_SYSCALL_ENTER +#define KMSAN_SYSCALL_EXIT +#define KMSAN_IST_ENTER(shift_ist) +#define KMSAN_IST_EXIT(shift_ist) +#define KMSAN_UNPOISON_PT_REGS + +#endif /* ifdef CONFIG_KMSAN */ +#endif /* ifndef _ASM_X86_KMSAN_H */ diff --git a/include/linux/kmsan-checks.h b/include/linux/kmsan-checks.h new file mode 100644 index 000000000000..2b25ced2f13e --- /dev/null +++ b/include/linux/kmsan-checks.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * KMSAN checks. + * TODO(glider): unite with kmsan.h? + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef _LINUX_KMSAN_CHECKS_H +#define _LINUX_KMSAN_CHECKS_H + +#include +#include + +struct i2c_msg; +struct page; +struct sk_buff; +struct urb; + +#ifdef CONFIG_KMSAN + +/* + * Helper functions that mark the return value initialized. + * Note that Clang ignores the inline attribute in the cases when a no_sanitize + * function is called from an instrumented one. + */ + +__no_sanitize_memory +static inline unsigned char KMSAN_INIT_1(unsigned char value) +{ + return value; +} + +__no_sanitize_memory +static inline unsigned short KMSAN_INIT_2(unsigned short value) +{ + return value; +} + +__no_sanitize_memory +static inline unsigned int KMSAN_INIT_4(unsigned int value) +{ + return value; +} + +__no_sanitize_memory +static inline unsigned long KMSAN_INIT_8(unsigned long value) +{ + return value; +} + +#define KMSAN_INIT_VALUE(val) \ + ({ \ + typeof(val) __ret; \ + switch (sizeof(val)) { \ + case 1: \ + *(unsigned char *)&__ret = KMSAN_INIT_1( \ + (unsigned char)val); \ + break; \ + case 2: \ + *(unsigned short *)&__ret = KMSAN_INIT_2( \ + (unsigned short)val); \ + break; \ + case 4: \ + *(unsigned int *)&__ret = KMSAN_INIT_4( \ + (unsigned int)val); \ + break; \ + case 8: \ + *(unsigned long *)&__ret = KMSAN_INIT_8( \ + (unsigned long)val); \ + break; \ + default: \ + BUILD_BUG_ON(1); \ + } \ + __ret; \ + }) /**/ + +void kmsan_ignore_page(struct page *page, int order); +void kmsan_poison_shadow(const void *address, size_t size, gfp_t flags); +void kmsan_unpoison_shadow(const void *address, size_t size); +void kmsan_check_memory(const void *address, size_t size); +void kmsan_check_skb(const struct sk_buff *skb); +void kmsan_handle_urb(const struct urb *urb, bool is_out); +void kmsan_handle_vprintk(const char **fmt, va_list args); +void kmsan_handle_i2c_transfer(struct i2c_msg *msgs, int num); +void kmsan_copy_to_user(const void *to, const void *from, size_t to_copy, + size_t left); +void *__msan_memcpy(void *dst, const void *src, u64 n); +void kmsan_enter_runtime(unsigned long *flags); +void kmsan_leave_runtime(unsigned long *flags); + +#else + +#define KMSAN_INIT_VALUE(value) (value) + +static inline void kmsan_ignore_page(struct page *page, int order) {} +static inline void kmsan_poison_shadow(const void *address, size_t size, + gfp_t flags) {} +static inline void kmsan_unpoison_shadow(const void *address, size_t size) {} +static inline void kmsan_check_memory(const void *address, size_t size) {} +static inline void kmsan_check_skb(const struct sk_buff *skb) {} +static inline void kmsan_handle_urb(const struct urb *urb, bool is_out) {} +static inline void kmsan_handle_vprintk(const char **fmt, va_list args) {} +static inline void kmsan_handle_i2c_transfer(struct i2c_msg *msgs, int num) {} +static inline void kmsan_copy_to_user( + const void *to, const void *from, size_t to_copy, size_t left) {} +static inline void *__msan_memcpy(void *dst, const void *src, size_t n) +{ + return NULL; +} + +static inline void kmsan_enter_runtime(unsigned long *flags) {} +static inline void kmsan_leave_runtime(unsigned long *flags) {} + +#endif + +#endif /* _LINUX_KMSAN_CHECKS_H */ diff --git a/include/linux/kmsan.h b/include/linux/kmsan.h new file mode 100644 index 000000000000..f5638bac368e --- /dev/null +++ b/include/linux/kmsan.h @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * KMSAN API for subsystems. + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef LINUX_KMSAN_H +#define LINUX_KMSAN_H + +#include +#include +#include +#include + +struct page; +struct kmem_cache; +struct task_struct; +struct vm_struct; + + +extern bool kmsan_ready; + +#ifdef CONFIG_KMSAN +void __init kmsan_initialize_shadow(void); +void __init kmsan_initialize(void); + +/* These constants are defined in the MSan LLVM instrumentation pass. */ +#define RETVAL_SIZE 800 +#define KMSAN_PARAM_SIZE 800 + +#define PARAM_ARRAY_SIZE (KMSAN_PARAM_SIZE / sizeof(depot_stack_handle_t)) + +struct kmsan_context_state { + char param_tls[KMSAN_PARAM_SIZE]; + char retval_tls[RETVAL_SIZE]; + char va_arg_tls[KMSAN_PARAM_SIZE]; + char va_arg_origin_tls[KMSAN_PARAM_SIZE]; + u64 va_arg_overflow_size_tls; + depot_stack_handle_t param_origin_tls[PARAM_ARRAY_SIZE]; + depot_stack_handle_t retval_origin_tls; + depot_stack_handle_t origin_tls; +}; + +struct kmsan_task_state { + bool allow_reporting; + struct kmsan_context_state cstate; +}; + +void kmsan_task_create(struct task_struct *task); +void kmsan_task_exit(struct task_struct *task); +void kmsan_alloc_shadow_for_region(void *start, size_t size); +int kmsan_alloc_page(struct page *page, unsigned int order, gfp_t flags); +void kmsan_gup_pgd_range(struct page **pages, int nr); +void kmsan_free_page(struct page *page, unsigned int order); +void kmsan_split_page(struct page *page, unsigned int order); +void kmsan_copy_page_meta(struct page *dst, struct page *src); + +void kmsan_poison_slab(struct page *page, gfp_t flags); +void kmsan_kmalloc_large(const void *ptr, size_t size, gfp_t flags); +void kmsan_kfree_large(const void *ptr); +void kmsan_kmalloc(struct kmem_cache *s, const void *object, size_t size, + gfp_t flags); +void kmsan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags); +void kmsan_slab_free(struct kmem_cache *s, void *object); + +void kmsan_slab_setup_object(struct kmem_cache *s, void *object); +void kmsan_post_alloc_hook(struct kmem_cache *s, gfp_t flags, + size_t size, void *object); + +/* vmap */ +void kmsan_vmap_page_range_noflush(unsigned long start, unsigned long end, + pgprot_t prot, struct page **pages); +void kmsan_vunmap_page_range(unsigned long addr, unsigned long end); + +/* ioremap */ +void kmsan_ioremap_page_range(unsigned long addr, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot); +void kmsan_iounmap_page_range(unsigned long start, unsigned long end); + +void kmsan_softirq_enter(void); +void kmsan_softirq_exit(void); + +void kmsan_clear_page(void *page_addr); + +#else + +static inline void __init kmsan_initialize_shadow(void) { } +static inline void __init kmsan_initialize(void) { } + +static inline void kmsan_task_create(struct task_struct *task) {} +static inline void kmsan_task_exit(struct task_struct *task) {} +static inline void kmsan_alloc_shadow_for_region(void *start, size_t size) {} +static inline int kmsan_alloc_page(struct page *page, unsigned int order, + gfp_t flags) +{ + return 0; +} +static inline void kmsan_gup_pgd_range(struct page **pages, int nr) {} +static inline void kmsan_free_page(struct page *page, unsigned int order) {} +static inline void kmsan_split_page(struct page *page, unsigned int order) {} +static inline void kmsan_copy_page_meta(struct page *dst, struct page *src) {} + +static inline void kmsan_poison_slab(struct page *page, gfp_t flags) {} +static inline void kmsan_kmalloc_large(const void *ptr, size_t size, + gfp_t flags) {} +static inline void kmsan_kfree_large(const void *ptr) {} +static inline void kmsan_kmalloc(struct kmem_cache *s, const void *object, + size_t size, gfp_t flags) {} +static inline void kmsan_slab_alloc(struct kmem_cache *s, void *object, + gfp_t flags) {} +static inline void kmsan_slab_free(struct kmem_cache *s, void *object) {} + +static inline void kmsan_slab_setup_object(struct kmem_cache *s, + void *object) {} +static inline void kmsan_post_alloc_hook(struct kmem_cache *s, gfp_t flags, + size_t size, void *object) {} + +static inline void kmsan_vmap_page_range_noflush(unsigned long start, + unsigned long end, + pgprot_t prot, + struct page **pages) {} +static inline void kmsan_vunmap_page_range(unsigned long start, + unsigned long end) {} + +static inline void kmsan_ioremap_page_range(unsigned long start, + unsigned long end, + phys_addr_t phys_addr, + pgprot_t prot) {} +static inline void kmsan_iounmap_page_range(unsigned long start, + unsigned long end) {} +static inline void kmsan_softirq_enter(void) {} +static inline void kmsan_softirq_exit(void) {} + +static inline void kmsan_clear_page(void *page_addr) {} +#endif + +#endif /* LINUX_KMSAN_H */ diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 93d97f9b0157..75c36318943d 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -756,6 +756,8 @@ config DEBUG_STACKOVERFLOW source "lib/Kconfig.kasan" +source "lib/Kconfig.kmsan" + endmenu # "Memory Debugging" config ARCH_HAS_KCOV diff --git a/lib/Kconfig.kmsan b/lib/Kconfig.kmsan new file mode 100644 index 000000000000..187dddfcf220 --- /dev/null +++ b/lib/Kconfig.kmsan @@ -0,0 +1,22 @@ +config HAVE_ARCH_KMSAN + bool + +if HAVE_ARCH_KMSAN + +config KMSAN + bool "KMSAN: detector of uninitialized memory use" + depends on SLUB && !KASAN + select STACKDEPOT + help + KMSAN is a dynamic detector of uses of uninitialized memory in the + kernel. It is based on compiler instrumentation provided by Clang + and thus requires Clang 10.0.0+ to build. + +config TEST_KMSAN + tristate "Module for testing KMSAN for bug detection" + depends on m && KMSAN + help + Test module that can trigger various uses of uninitialized memory + detectable by KMSAN. + +endif diff --git a/mm/kmsan/Makefile b/mm/kmsan/Makefile new file mode 100644 index 000000000000..ccf6d2d00a7a --- /dev/null +++ b/mm/kmsan/Makefile @@ -0,0 +1,4 @@ +obj-y := kmsan.o kmsan_instr.o kmsan_init.o kmsan_entry.o kmsan_hooks.o kmsan_report.o kmsan_shadow.o + +KMSAN_SANITIZE := n +KCOV_INSTRUMENT := n diff --git a/mm/kmsan/kmsan.c b/mm/kmsan/kmsan.c new file mode 100644 index 000000000000..8009149ee20a --- /dev/null +++ b/mm/kmsan/kmsan.c @@ -0,0 +1,570 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN runtime library. + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../slab.h" +#include "kmsan.h" + +/* + * Some kernel asm() calls mention the non-existing |__force_order| variable + * in the asm constraints to preserve the order of accesses to control + * registers. KMSAN turns those mentions into actual memory accesses, therefore + * the variable is now required to link the kernel. + */ +unsigned long __force_order; + +bool kmsan_ready; +#define KMSAN_STACK_DEPTH 64 +#define MAX_CHAIN_DEPTH 7 + +/* + * According to Documentation/x86/kernel-stacks, kernel code can run on the + * following stacks: + * - regular task stack - when executing the task code + * - interrupt stack - when handling external hardware interrupts and softirqs + * - NMI stack + * 0 is for regular interrupts, 1 for softirqs, 2 for NMI. + * Because interrupts may nest, trying to use a new context for every new + * interrupt. + */ +/* [0] for dummy per-CPU context. */ +DEFINE_PER_CPU(struct kmsan_context_state[KMSAN_NESTED_CONTEXT_MAX], + kmsan_percpu_cstate); +/* 0 for task context, |i>0| for kmsan_context_state[i]. */ +DEFINE_PER_CPU(int, kmsan_context_level); +DEFINE_PER_CPU(int, kmsan_in_interrupt); +DEFINE_PER_CPU(bool, kmsan_in_softirq); +DEFINE_PER_CPU(bool, kmsan_in_nmi); +DEFINE_PER_CPU(int, kmsan_in_runtime); +/* TODO(glider): debug-only. */ +DEFINE_PER_CPU(unsigned long, kmsan_runtime_last_caller); + +struct kmsan_context_state *task_kmsan_context_state(void) +{ + int cpu = smp_processor_id(); + int level = this_cpu_read(kmsan_context_level); + struct kmsan_context_state *ret; + + if (!kmsan_ready || IN_RUNTIME()) { + ret = &per_cpu(kmsan_percpu_cstate[0], cpu); + __memset(ret, 0, sizeof(struct kmsan_context_state)); + return ret; + } + + if (!level) + ret = ¤t->kmsan.cstate; + else + ret = &per_cpu(kmsan_percpu_cstate[level], cpu); + return ret; +} + +void kmsan_internal_task_create(struct task_struct *task) +{ + struct kmsan_task_state *state = &task->kmsan; + + __memset(state, 0, sizeof(struct kmsan_task_state)); + state->allow_reporting = true; +} + +void kmsan_internal_memset_shadow(void *addr, int b, size_t size, + bool checked) +{ + void *shadow_start; + u64 page_offset, address = (u64)addr; + size_t to_fill; + + BUG_ON(!metadata_is_contiguous(addr, size, META_SHADOW)); + while (size) { + page_offset = address % PAGE_SIZE; + to_fill = min(PAGE_SIZE - page_offset, (u64)size); + shadow_start = kmsan_get_metadata((void *)address, to_fill, + META_SHADOW); + if (!shadow_start) { + if (checked) { + kmsan_pr_err("WARNING: not memsetting %d bytes starting at %px, because the shadow is NULL\n", to_fill, address); + BUG(); + } + /* Otherwise just move on. */ + } else { + __memset(shadow_start, b, to_fill); + } + address += to_fill; + size -= to_fill; + } +} + +void kmsan_internal_poison_shadow(void *address, size_t size, + gfp_t flags, unsigned int poison_flags) +{ + bool checked = poison_flags & KMSAN_POISON_CHECK; + depot_stack_handle_t handle; + u32 extra_bits = 0; + + if (poison_flags & KMSAN_POISON_FREE) + extra_bits = 1; + kmsan_internal_memset_shadow(address, -1, size, checked); + handle = kmsan_save_stack_with_flags(flags, extra_bits); + kmsan_set_origin_checked(address, size, handle, checked); +} + +void kmsan_internal_unpoison_shadow(void *address, size_t size, bool checked) +{ + kmsan_internal_memset_shadow(address, 0, size, checked); + kmsan_set_origin_checked(address, size, 0, checked); +} + +depot_stack_handle_t kmsan_save_stack_with_flags(gfp_t flags, + unsigned int reserved) +{ + depot_stack_handle_t handle; + unsigned long entries[KMSAN_STACK_DEPTH]; + unsigned int nr_entries; + + nr_entries = stack_trace_save(entries, KMSAN_STACK_DEPTH, 0); + filter_irq_stacks(entries, nr_entries); + + /* Don't sleep (see might_sleep_if() in __alloc_pages_nodemask()). */ + flags &= ~__GFP_DIRECT_RECLAIM; + + handle = stack_depot_save(entries, nr_entries, flags); + return set_dsh_extra_bits(handle, reserved); +} + +/* + * Depending on the value of is_memmove, this serves as both a memcpy and a + * memmove implementation. + * + * As with the regular memmove, do the following: + * - if src and dst don't overlap, use memcpy(); + * - if src and dst overlap: + * - if src > dst, use memcpy(); + * - if src < dst, use reverse-memcpy. + * Why this is correct: + * - problems may arise if for some part of the overlapping region we + * overwrite its shadow with a new value before copying it somewhere. + * But there's a 1:1 mapping between the kernel memory and its shadow, + * therefore if this doesn't happen with the kernel memory it can't happen + * with the shadow. + */ +void kmsan_memcpy_memmove_metadata(void *dst, void *src, size_t n, + bool is_memmove) +{ + void *shadow_src, *shadow_dst; + depot_stack_handle_t *origin_src, *origin_dst; + int src_slots, dst_slots, i, iter, step, skip_bits; + depot_stack_handle_t old_origin = 0, chain_origin, new_origin = 0; + u32 *align_shadow_src, shadow; + bool backwards; + + BUG_ON(!metadata_is_contiguous(dst, n, META_SHADOW)); + BUG_ON(!metadata_is_contiguous(src, n, META_SHADOW)); + + shadow_dst = kmsan_get_metadata(dst, n, META_SHADOW); + if (!shadow_dst) + return; + + shadow_src = kmsan_get_metadata(src, n, META_SHADOW); + if (!shadow_src) { + /* + * |src| is untracked: zero out destination shadow, ignore the + * origins, we're done. + */ + __memset(shadow_dst, 0, n); + return; + } + if (is_memmove) + __memmove(shadow_dst, shadow_src, n); + else + __memcpy(shadow_dst, shadow_src, n); + + origin_dst = kmsan_get_metadata(dst, n, META_ORIGIN); + origin_src = kmsan_get_metadata(src, n, META_ORIGIN); + BUG_ON(!origin_dst || !origin_src); + BUG_ON(!metadata_is_contiguous(dst, n, META_ORIGIN)); + BUG_ON(!metadata_is_contiguous(src, n, META_ORIGIN)); + src_slots = (ALIGN((u64)src + n, ORIGIN_SIZE) - + ALIGN_DOWN((u64)src, ORIGIN_SIZE)) / ORIGIN_SIZE; + dst_slots = (ALIGN((u64)dst + n, ORIGIN_SIZE) - + ALIGN_DOWN((u64)dst, ORIGIN_SIZE)) / ORIGIN_SIZE; + BUG_ON(!src_slots || !dst_slots); + BUG_ON((src_slots < 1) || (dst_slots < 1)); + BUG_ON((src_slots - dst_slots > 1) || (dst_slots - src_slots < -1)); + + backwards = is_memmove && (dst > src); + i = backwards ? min(src_slots, dst_slots) - 1 : 0; + iter = backwards ? -1 : 1; + + align_shadow_src = (u32 *)ALIGN_DOWN((u64)shadow_src, ORIGIN_SIZE); + for (step = 0; step < min(src_slots, dst_slots); step++, i += iter) { + BUG_ON(i < 0); + shadow = align_shadow_src[i]; + if (i == 0) { + /* + * If |src| isn't aligned on ORIGIN_SIZE, don't + * look at the first |src % ORIGIN_SIZE| bytes + * of the first shadow slot. + */ + skip_bits = ((u64)src % ORIGIN_SIZE) * 8; + shadow = (shadow << skip_bits) >> skip_bits; + } + if (i == src_slots - 1) { + /* + * If |src + n| isn't aligned on + * ORIGIN_SIZE, don't look at the last + * |(src + n) % ORIGIN_SIZE| bytes of the + * last shadow slot. + */ + skip_bits = (((u64)src + n) % ORIGIN_SIZE) * 8; + shadow = (shadow >> skip_bits) << skip_bits; + } + /* + * Overwrite the origin only if the corresponding + * shadow is nonempty. + */ + if (origin_src[i] && (origin_src[i] != old_origin) && shadow) { + old_origin = origin_src[i]; + chain_origin = kmsan_internal_chain_origin(old_origin); + /* + * kmsan_internal_chain_origin() may return + * NULL, but we don't want to lose the previous + * origin value. + */ + if (chain_origin) + new_origin = chain_origin; + else + new_origin = old_origin; + } + if (shadow) + origin_dst[i] = new_origin; + else + origin_dst[i] = 0; + } +} + +void kmsan_memcpy_metadata(void *dst, void *src, size_t n) +{ + kmsan_memcpy_memmove_metadata(dst, src, n, /*is_memmove*/false); +} + +void kmsan_memmove_metadata(void *dst, void *src, size_t n) +{ + kmsan_memcpy_memmove_metadata(dst, src, n, /*is_memmove*/true); +} + +depot_stack_handle_t kmsan_internal_chain_origin(depot_stack_handle_t id) +{ + depot_stack_handle_t handle; + unsigned long entries[3]; + u64 magic = KMSAN_CHAIN_MAGIC_ORIGIN_FULL; + int depth = 0; + static int skipped; + u32 extra_bits; + + if (!kmsan_ready) + return 0; + + if (!id) + return id; + /* + * Make sure we have enough spare bits in |id| to hold the UAF bit and + * the chain depth. + */ + BUILD_BUG_ON((1 << STACK_DEPOT_EXTRA_BITS) <= (MAX_CHAIN_DEPTH << 1)); + + extra_bits = get_dsh_extra_bits(id); + + depth = extra_bits >> 1; + if (depth >= MAX_CHAIN_DEPTH) { + skipped++; + if (skipped % 10000 == 0) { + kmsan_pr_err("not chained %d origins\n", skipped); + dump_stack(); + kmsan_print_origin(id); + } + return id; + } + depth++; + /* Lowest bit is the UAF flag, higher bits hold the depth. */ + extra_bits = (depth << 1) | (extra_bits & 1); + /* TODO(glider): how do we figure out we've dropped some frames? */ + entries[0] = magic + depth; + entries[1] = kmsan_save_stack_with_flags(GFP_ATOMIC, extra_bits); + entries[2] = id; + handle = stack_depot_save(entries, ARRAY_SIZE(entries), GFP_ATOMIC); + return set_dsh_extra_bits(handle, extra_bits); +} + +void kmsan_write_aligned_origin(void *var, size_t size, u32 origin) +{ + u32 *var_cast = (u32 *)var; + int i; + + BUG_ON((u64)var_cast % ORIGIN_SIZE); + BUG_ON(size % ORIGIN_SIZE); + for (i = 0; i < size / ORIGIN_SIZE; i++) + var_cast[i] = origin; +} + +/* + * TODO(glider): writing an initialized byte shouldn't zero out the origin, if + * the remaining three bytes are uninitialized. + */ +void kmsan_internal_set_origin(void *addr, int size, u32 origin) +{ + void *origin_start; + u64 address = (u64)addr, page_offset; + size_t to_fill, pad = 0; + + if (!IS_ALIGNED(address, ORIGIN_SIZE)) { + pad = address % ORIGIN_SIZE; + address -= pad; + size += pad; + } + + while (size > 0) { + page_offset = address % PAGE_SIZE; + to_fill = min(PAGE_SIZE - page_offset, (u64)size); + /* write at least ORIGIN_SIZE bytes */ + to_fill = ALIGN(to_fill, ORIGIN_SIZE); + BUG_ON(!to_fill); + origin_start = kmsan_get_metadata((void *)address, to_fill, + META_ORIGIN); + address += to_fill; + size -= to_fill; + if (!origin_start) + /* Can happen e.g. if the memory is untracked. */ + continue; + kmsan_write_aligned_origin(origin_start, to_fill, origin); + } +} + +void kmsan_set_origin_checked(void *addr, int size, u32 origin, bool checked) +{ + if (checked && !metadata_is_contiguous(addr, size, META_ORIGIN)) { + kmsan_pr_err("WARNING: not setting origin for %d bytes starting at %px, because the metadata is incontiguous\n", size, addr); + BUG(); + } + kmsan_internal_set_origin(addr, size, origin); +} + +struct page *vmalloc_to_page_or_null(void *vaddr) +{ + struct page *page; + + if (!kmsan_internal_is_vmalloc_addr(vaddr) && + !kmsan_internal_is_module_addr(vaddr)) + return NULL; + page = vmalloc_to_page(vaddr); + if (pfn_valid(page_to_pfn(page))) + return page; + else + return NULL; +} + +void kmsan_internal_check_memory(void *addr, size_t size, const void *user_addr, + int reason) +{ + unsigned long irq_flags; + unsigned long addr64 = (unsigned long)addr; + unsigned char *shadow = NULL; + depot_stack_handle_t *origin = NULL; + depot_stack_handle_t cur_origin = 0, new_origin = 0; + int cur_off_start = -1; + int i, chunk_size; + size_t pos = 0; + + BUG_ON(!metadata_is_contiguous(addr, size, META_SHADOW)); + if (size <= 0) + return; + while (pos < size) { + chunk_size = min(size - pos, + PAGE_SIZE - ((addr64 + pos) % PAGE_SIZE)); + shadow = kmsan_get_metadata((void *)(addr64 + pos), chunk_size, + META_SHADOW); + if (!shadow) { + /* + * This page is untracked. If there were uninitialized + * bytes before, report them. + */ + if (cur_origin) { + ENTER_RUNTIME(irq_flags); + kmsan_report(cur_origin, addr, size, + cur_off_start, pos - 1, user_addr, + reason); + LEAVE_RUNTIME(irq_flags); + } + cur_origin = 0; + cur_off_start = -1; + pos += chunk_size; + continue; + } + for (i = 0; i < chunk_size; i++) { + if (!shadow[i]) { + /* + * This byte is unpoisoned. If there were + * poisoned bytes before, report them. + */ + if (cur_origin) { + ENTER_RUNTIME(irq_flags); + kmsan_report(cur_origin, addr, size, + cur_off_start, pos + i - 1, + user_addr, reason); + LEAVE_RUNTIME(irq_flags); + } + cur_origin = 0; + cur_off_start = -1; + continue; + } + origin = kmsan_get_metadata((void *)(addr64 + pos + i), + chunk_size - i, META_ORIGIN); + BUG_ON(!origin); + new_origin = *origin; + /* + * Encountered new origin - report the previous + * uninitialized range. + */ + if (cur_origin != new_origin) { + if (cur_origin) { + ENTER_RUNTIME(irq_flags); + kmsan_report(cur_origin, addr, size, + cur_off_start, pos + i - 1, + user_addr, reason); + LEAVE_RUNTIME(irq_flags); + } + cur_origin = new_origin; + cur_off_start = pos + i; + } + } + pos += chunk_size; + } + BUG_ON(pos != size); + if (cur_origin) { + ENTER_RUNTIME(irq_flags); + kmsan_report(cur_origin, addr, size, cur_off_start, pos - 1, + user_addr, reason); + LEAVE_RUNTIME(irq_flags); + } +} + +/* + * TODO(glider): this check shouldn't be performed for origin pages, because + * they're always accessed after the shadow pages. + */ +bool metadata_is_contiguous(void *addr, size_t size, bool is_origin) +{ + u64 cur_addr = (u64)addr, next_addr; + char *cur_meta = NULL, *next_meta = NULL; + depot_stack_handle_t *origin_p; + bool all_untracked = false; + const char *fname = is_origin ? "origin" : "shadow"; + + if (!size) + return true; + + /* The whole range belongs to the same page. */ + if (ALIGN_DOWN(cur_addr + size - 1, PAGE_SIZE) == + ALIGN_DOWN(cur_addr, PAGE_SIZE)) + return true; + cur_meta = kmsan_get_metadata((void *)cur_addr, 1, is_origin); + if (!cur_meta) + all_untracked = true; + for (next_addr = cur_addr + PAGE_SIZE; next_addr < (u64)addr + size; + cur_addr = next_addr, + cur_meta = next_meta, + next_addr += PAGE_SIZE) { + next_meta = kmsan_get_metadata((void *)next_addr, 1, is_origin); + if (!next_meta) { + if (!all_untracked) + goto report; + continue; + } + if ((u64)cur_meta == ((u64)next_meta - PAGE_SIZE)) + continue; + goto report; + } + return true; + +report: + kmsan_pr_err("BUG: attempting to access two shadow page ranges.\n"); + dump_stack(); + kmsan_pr_err("\n"); + kmsan_pr_err("Access of size %d at %px.\n", size, addr); + kmsan_pr_err("Addresses belonging to different ranges: %px and %px\n", + cur_addr, next_addr); + kmsan_pr_err("page[0].%s: %px, page[1].%s: %px\n", + fname, cur_meta, fname, next_meta); + origin_p = kmsan_get_metadata(addr, 1, META_ORIGIN); + if (origin_p) { + kmsan_pr_err("Origin: %08x\n", *origin_p); + kmsan_print_origin(*origin_p); + } else { + kmsan_pr_err("Origin: unavailable\n"); + } + return false; +} + +/* + * Dummy replacement for __builtin_return_address() which may crash without + * frame pointers. + */ +void *kmsan_internal_return_address(int arg) +{ +#ifdef CONFIG_UNWINDER_FRAME_POINTER + switch (arg) { + case 1: + return __builtin_return_address(1); + case 2: + return __builtin_return_address(2); + default: + BUG(); + } +#else + unsigned long entries[1]; + struct stack_trace trace = { + .nr_entries = 0, + .entries = entries, + .max_entries = 1, + .skip = arg + }; + save_stack_trace(&trace); + return entries[0]; +#endif +} + +bool kmsan_internal_is_module_addr(void *vaddr) +{ + return ((u64)vaddr >= MODULES_VADDR) && ((u64)vaddr < MODULES_END); +} + +bool kmsan_internal_is_vmalloc_addr(void *addr) +{ + return ((u64)addr >= VMALLOC_START) && ((u64)addr < VMALLOC_END); +} diff --git a/mm/kmsan/kmsan.h b/mm/kmsan/kmsan.h new file mode 100644 index 000000000000..015e402e9f9d --- /dev/null +++ b/mm/kmsan/kmsan.h @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * KMSAN internal declarations. + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __MM_KMSAN_KMSAN_H +#define __MM_KMSAN_KMSAN_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kmsan_shadow.h" + +#define KMSAN_MAGIC_MASK 0xffffffffff00 +#define KMSAN_ALLOCA_MAGIC_ORIGIN 0x4110c4071900 +#define KMSAN_CHAIN_MAGIC_ORIGIN_FULL 0xd419170cba00 + +#define KMSAN_POISON_NOCHECK 0x0 +#define KMSAN_POISON_CHECK 0x1 +#define KMSAN_POISON_FREE 0x2 + +#define ORIGIN_SIZE 4 + +#define META_SHADOW (false) +#define META_ORIGIN (true) + +#define KMSAN_NESTED_CONTEXT_MAX (8) +/* [0] for dummy per-CPU context */ +DECLARE_PER_CPU(struct kmsan_context_state[KMSAN_NESTED_CONTEXT_MAX], + kmsan_percpu_cstate); +/* 0 for task context, |i>0| for kmsan_context_state[i]. */ +DECLARE_PER_CPU(int, kmsan_context_level); +DECLARE_PER_CPU(int, kmsan_in_interrupt); +DECLARE_PER_CPU(bool, kmsan_in_softirq); +DECLARE_PER_CPU(bool, kmsan_in_nmi); + +extern spinlock_t report_lock; + +/* Stolen from kernel/printk/internal.h */ +#define PRINTK_SAFE_CONTEXT_MASK 0x3fffffff +/* Defined in kernel/printk/printk_safe.c */ +DECLARE_PER_CPU(int, printk_context); + +/* Only print iff printk hasn't acquired the console lock. */ +#define kmsan_pr_err(...) \ + do { \ + if (!(this_cpu_read(printk_context) & \ + PRINTK_SAFE_CONTEXT_MASK)) \ + pr_err(__VA_ARGS__); \ + } while (0) + +void kmsan_print_origin(depot_stack_handle_t origin); +void kmsan_report(depot_stack_handle_t origin, + void *address, int size, int off_first, int off_last, + const void *user_addr, int reason); + + +enum KMSAN_BUG_REASON { + REASON_ANY = 0, + REASON_COPY_TO_USER = 1, + REASON_USE_AFTER_FREE = 2, + REASON_SUBMIT_URB = 3, +}; + +/* + * When a compiler hook is invoked, it may make a call to instrumented code + * and eventually call itself recursively. To avoid that, we protect the + * runtime entry points with ENTER_RUNTIME()/LEAVE_RUNTIME() macros and exit + * the hook if IN_RUNTIME() is true. But when an interrupt occurs inside the + * runtime, the hooks won’t run either, which may lead to errors. + * Therefore we have to disable interrupts inside the runtime. + */ +DECLARE_PER_CPU(int, kmsan_in_runtime); +DECLARE_PER_CPU(unsigned long, kmsan_runtime_last_caller); +#define IN_RUNTIME() (this_cpu_read(kmsan_in_runtime)) +#define ENTER_RUNTIME(irq_flags) \ + do { \ + preempt_disable(); \ + local_irq_save(irq_flags); \ + stop_nmi(); \ + this_cpu_inc(kmsan_in_runtime); \ + this_cpu_write(kmsan_runtime_last_caller, _THIS_IP_); \ + BUG_ON(this_cpu_read(kmsan_in_runtime) > 1); \ + } while (0) +#define LEAVE_RUNTIME(irq_flags) \ + do { \ + this_cpu_dec(kmsan_in_runtime); \ + if (this_cpu_read(kmsan_in_runtime)) { \ + kmsan_pr_err("kmsan_in_runtime: %d, last_caller: %pS\n", \ + this_cpu_read(kmsan_in_runtime), \ + this_cpu_read(kmsan_runtime_last_caller)); \ + BUG(); \ + } \ + restart_nmi(); \ + local_irq_restore(irq_flags); \ + preempt_enable(); } while (0) + +void kmsan_memcpy_metadata(void *dst, void *src, size_t n); +void kmsan_memmove_metadata(void *dst, void *src, size_t n); + +depot_stack_handle_t kmsan_save_stack(void); +depot_stack_handle_t kmsan_save_stack_with_flags(gfp_t flags, + unsigned int extra_bits); +void kmsan_internal_poison_shadow(void *address, size_t size, gfp_t flags, + unsigned int poison_flags); +void kmsan_internal_unpoison_shadow(void *address, size_t size, bool checked); +void kmsan_internal_memset_shadow(void *address, int b, size_t size, + bool checked); +depot_stack_handle_t kmsan_internal_chain_origin(depot_stack_handle_t id); +void kmsan_write_aligned_origin(void *var, size_t size, u32 origin); + +void kmsan_internal_task_create(struct task_struct *task); +void kmsan_internal_set_origin(void *addr, int size, u32 origin); +void kmsan_set_origin_checked(void *addr, int size, u32 origin, bool checked); + +struct kmsan_context_state *task_kmsan_context_state(void); + +bool metadata_is_contiguous(void *addr, size_t size, bool is_origin); +void kmsan_internal_check_memory(void *addr, size_t size, const void *user_addr, + int reason); + +struct page *vmalloc_to_page_or_null(void *vaddr); + +/* Declared in mm/vmalloc.c */ +void __vunmap_page_range(unsigned long addr, unsigned long end); +int __vmap_page_range_noflush(unsigned long start, unsigned long end, + pgprot_t prot, struct page **pages); + +void *kmsan_internal_return_address(int arg); +bool kmsan_internal_is_module_addr(void *vaddr); +bool kmsan_internal_is_vmalloc_addr(void *addr); + +#endif /* __MM_KMSAN_KMSAN_H */ diff --git a/mm/kmsan/kmsan_entry.c b/mm/kmsan/kmsan_entry.c new file mode 100644 index 000000000000..9511a7dad541 --- /dev/null +++ b/mm/kmsan/kmsan_entry.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN hooks for entry_64.S + * + * Copyright (C) 2018-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include "kmsan.h" + +static void kmsan_context_enter(void) +{ + int level = this_cpu_read(kmsan_context_level) + 1; + + BUG_ON(level >= KMSAN_NESTED_CONTEXT_MAX); + this_cpu_write(kmsan_context_level, level); +} + +static void kmsan_context_exit(void) +{ + int level = this_cpu_read(kmsan_context_level) - 1; + + BUG_ON(level < 0); + this_cpu_write(kmsan_context_level, level); +} + +void kmsan_interrupt_enter(void) +{ + int in_interrupt = this_cpu_read(kmsan_in_interrupt); + + /* Turns out it's possible for in_interrupt to be >0 here. */ + kmsan_context_enter(); + BUG_ON(in_interrupt > 1); + /* Can't check preempt_count() here, it may be zero. */ + this_cpu_write(kmsan_in_interrupt, in_interrupt + 1); +} +EXPORT_SYMBOL(kmsan_interrupt_enter); + +void kmsan_interrupt_exit(void) +{ + int in_interrupt = this_cpu_read(kmsan_in_interrupt); + + BUG_ON(!in_interrupt); + kmsan_context_exit(); + /* Can't check preempt_count() here, it may be zero. */ + this_cpu_write(kmsan_in_interrupt, in_interrupt - 1); +} +EXPORT_SYMBOL(kmsan_interrupt_exit); + +void kmsan_softirq_enter(void) +{ + bool in_softirq = this_cpu_read(kmsan_in_softirq); + + BUG_ON(in_softirq); + kmsan_context_enter(); + /* Can't check preempt_count() here, it may be zero. */ + this_cpu_write(kmsan_in_softirq, true); +} +EXPORT_SYMBOL(kmsan_softirq_enter); + +void kmsan_softirq_exit(void) +{ + bool in_softirq = this_cpu_read(kmsan_in_softirq); + + BUG_ON(!in_softirq); + kmsan_context_exit(); + /* Can't check preempt_count() here, it may be zero. */ + this_cpu_write(kmsan_in_softirq, false); +} +EXPORT_SYMBOL(kmsan_softirq_exit); + +void kmsan_nmi_enter(void) +{ + bool in_nmi = this_cpu_read(kmsan_in_nmi); + + BUG_ON(in_nmi); + BUG_ON(preempt_count() & NMI_MASK); + kmsan_context_enter(); + this_cpu_write(kmsan_in_nmi, true); +} +EXPORT_SYMBOL(kmsan_nmi_enter); + +void kmsan_nmi_exit(void) +{ + bool in_nmi = this_cpu_read(kmsan_in_nmi); + + BUG_ON(!in_nmi); + BUG_ON(preempt_count() & NMI_MASK); + kmsan_context_exit(); + this_cpu_write(kmsan_in_nmi, false); + +} +EXPORT_SYMBOL(kmsan_nmi_exit); + +void kmsan_syscall_enter(void) +{ + +} +EXPORT_SYMBOL(kmsan_syscall_enter); + +void kmsan_syscall_exit(void) +{ + +} +EXPORT_SYMBOL(kmsan_syscall_exit); + +void kmsan_ist_enter(u64 shift_ist) +{ + kmsan_context_enter(); +} +EXPORT_SYMBOL(kmsan_ist_enter); + +void kmsan_ist_exit(u64 shift_ist) +{ + kmsan_context_exit(); +} +EXPORT_SYMBOL(kmsan_ist_exit); + +void kmsan_unpoison_pt_regs(struct pt_regs *regs) +{ + if (!kmsan_ready || IN_RUNTIME()) + return; + kmsan_internal_unpoison_shadow(regs, sizeof(*regs), /*checked*/true); +} +EXPORT_SYMBOL(kmsan_unpoison_pt_regs); diff --git a/mm/kmsan/kmsan_hooks.c b/mm/kmsan/kmsan_hooks.c new file mode 100644 index 000000000000..c0b941be528b --- /dev/null +++ b/mm/kmsan/kmsan_hooks.c @@ -0,0 +1,416 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN hooks for kernel subsystems. + * + * These functions handle creation of KMSAN metadata for memory allocations. + * + * Copyright (C) 2018-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../slab.h" +#include "kmsan.h" + +/* TODO(glider): do we need to export these symbols? */ + +/* + * The functions may call back to instrumented code, which, in turn, may call + * these hooks again. To avoid re-entrancy, we use __GFP_NO_KMSAN_SHADOW. + * Instrumented functions shouldn't be called under + * ENTER_RUNTIME()/LEAVE_RUNTIME(), because this will lead to skipping + * effects of functions like memset() inside instrumented code. + */ +/* Called from kernel/kthread.c, kernel/fork.c */ +void kmsan_task_create(struct task_struct *task) +{ + unsigned long irq_flags; + + if (!task) + return; + ENTER_RUNTIME(irq_flags); + kmsan_internal_task_create(task); + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(kmsan_task_create); + + +/* Called from kernel/exit.c */ +void kmsan_task_exit(struct task_struct *task) +{ + unsigned long irq_flags; + struct kmsan_task_state *state = &task->kmsan; + + if (!kmsan_ready || IN_RUNTIME()) + return; + + ENTER_RUNTIME(irq_flags); + state->allow_reporting = false; + + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(kmsan_task_exit); + +/* Called from mm/slub.c */ +void kmsan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags) +{ + unsigned long irq_flags; + + if (unlikely(object == NULL)) + return; + if (!kmsan_ready || IN_RUNTIME()) + return; + /* + * There's a ctor or this is an RCU cache - do nothing. The memory + * status hasn't changed since last use. + */ + if (s->ctor || (s->flags & SLAB_TYPESAFE_BY_RCU)) + return; + + ENTER_RUNTIME(irq_flags); + if (flags & __GFP_ZERO) { + kmsan_internal_unpoison_shadow(object, s->object_size, + KMSAN_POISON_CHECK); + } else { + kmsan_internal_poison_shadow(object, s->object_size, flags, + KMSAN_POISON_CHECK); + } + LEAVE_RUNTIME(irq_flags); +} + +/* Called from mm/slub.c */ +void kmsan_slab_free(struct kmem_cache *s, void *object) +{ + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + ENTER_RUNTIME(irq_flags); + + /* RCU slabs could be legally used after free within the RCU period */ + if (unlikely(s->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON))) + goto leave; + if (s->ctor) + goto leave; + kmsan_internal_poison_shadow(object, s->object_size, + GFP_KERNEL, + KMSAN_POISON_CHECK | KMSAN_POISON_FREE); +leave: + LEAVE_RUNTIME(irq_flags); +} + +/* Called from mm/slub.c */ +void kmsan_kmalloc_large(const void *ptr, size_t size, gfp_t flags) +{ + unsigned long irq_flags; + + if (unlikely(ptr == NULL)) + return; + if (!kmsan_ready || IN_RUNTIME()) + return; + ENTER_RUNTIME(irq_flags); + if (flags & __GFP_ZERO) { + kmsan_internal_unpoison_shadow((void *)ptr, size, + /*checked*/true); + } else { + kmsan_internal_poison_shadow((void *)ptr, size, flags, + KMSAN_POISON_CHECK); + } + LEAVE_RUNTIME(irq_flags); +} + +/* Called from mm/slub.c */ +void kmsan_kfree_large(const void *ptr) +{ + struct page *page; + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + ENTER_RUNTIME(irq_flags); + page = virt_to_head_page((void *)ptr); + BUG_ON(ptr != page_address(page)); + kmsan_internal_poison_shadow( + (void *)ptr, PAGE_SIZE << compound_order(page), GFP_KERNEL, + KMSAN_POISON_CHECK | KMSAN_POISON_FREE); + LEAVE_RUNTIME(irq_flags); +} + + +static unsigned long vmalloc_shadow(unsigned long addr) +{ + return (unsigned long)kmsan_get_metadata((void *)addr, 1, META_SHADOW); +} + +static unsigned long vmalloc_origin(unsigned long addr) +{ + return (unsigned long)kmsan_get_metadata((void *)addr, 1, META_ORIGIN); +} + +/* Called from mm/vmalloc.c */ +void kmsan_vunmap_page_range(unsigned long start, unsigned long end) +{ + __vunmap_page_range(vmalloc_shadow(start), vmalloc_shadow(end)); + __vunmap_page_range(vmalloc_origin(start), vmalloc_origin(end)); +} + +/* Called from lib/ioremap.c */ +/* + * This function creates new shadow/origin pages for the physical pages mapped + * into the virtual memory. If those physical pages already had shadow/origin, + * those are ignored. + */ +void kmsan_ioremap_page_range(unsigned long start, unsigned long end, + phys_addr_t phys_addr, pgprot_t prot) +{ + unsigned long irq_flags; + struct page *shadow, *origin; + int i, nr; + unsigned long off = 0; + gfp_t gfp_mask = GFP_KERNEL | __GFP_ZERO | __GFP_NO_KMSAN_SHADOW; + + if (!kmsan_ready || IN_RUNTIME()) + return; + + nr = (end - start) / PAGE_SIZE; + ENTER_RUNTIME(irq_flags); + for (i = 0; i < nr; i++, off += PAGE_SIZE) { + shadow = alloc_pages(gfp_mask, 1); + origin = alloc_pages(gfp_mask, 1); + __vmap_page_range_noflush(vmalloc_shadow(start + off), + vmalloc_shadow(start + off + PAGE_SIZE), + prot, &shadow); + __vmap_page_range_noflush(vmalloc_origin(start + off), + vmalloc_origin(start + off + PAGE_SIZE), + prot, &origin); + } + flush_cache_vmap(vmalloc_shadow(start), vmalloc_shadow(end)); + flush_cache_vmap(vmalloc_origin(start), vmalloc_origin(end)); + LEAVE_RUNTIME(irq_flags); +} + +void kmsan_iounmap_page_range(unsigned long start, unsigned long end) +{ + int i, nr; + struct page *shadow, *origin; + unsigned long v_shadow, v_origin; + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + + nr = (end - start) / PAGE_SIZE; + ENTER_RUNTIME(irq_flags); + v_shadow = (unsigned long)vmalloc_shadow(start); + v_origin = (unsigned long)vmalloc_origin(start); + for (i = 0; i < nr; i++, v_shadow += PAGE_SIZE, v_origin += PAGE_SIZE) { + shadow = vmalloc_to_page_or_null((void *)v_shadow); + origin = vmalloc_to_page_or_null((void *)v_origin); + __vunmap_page_range(v_shadow, v_shadow + PAGE_SIZE); + __vunmap_page_range(v_origin, v_origin + PAGE_SIZE); + if (shadow) + __free_pages(shadow, 1); + if (origin) + __free_pages(origin, 1); + } + LEAVE_RUNTIME(irq_flags); +} + +/* Called from include/linux/uaccess.h, include/linux/uaccess.h */ +void kmsan_copy_to_user(const void *to, const void *from, + size_t to_copy, size_t left) +{ + void *shadow; + + if (!kmsan_ready || IN_RUNTIME()) + return; + /* + * At this point we've copied the memory already. It's hard to check it + * before copying, as the size of actually copied buffer is unknown. + */ + + /* copy_to_user() may copy zero bytes. No need to check. */ + if (!to_copy) + return; + /* Or maybe copy_to_user() failed to copy anything. */ + if (to_copy == left) + return; + if ((u64)to < TASK_SIZE) { + /* This is a user memory access, check it. */ + kmsan_internal_check_memory((void *)from, to_copy - left, to, + REASON_COPY_TO_USER); + return; + } + /* Otherwise this is a kernel memory access. This happens when a compat + * syscall passes an argument allocated on the kernel stack to a real + * syscall. + * Don't check anything, just copy the shadow of the copied bytes. + */ + shadow = kmsan_get_metadata((void *)to, to_copy - left, META_SHADOW); + if (shadow) + kmsan_memcpy_metadata((void *)to, (void *)from, to_copy - left); +} +EXPORT_SYMBOL(kmsan_copy_to_user); + +void kmsan_poison_shadow(const void *address, size_t size, gfp_t flags) +{ + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + ENTER_RUNTIME(irq_flags); + /* The users may want to poison/unpoison random memory. */ + kmsan_internal_poison_shadow((void *)address, size, flags, + KMSAN_POISON_NOCHECK); + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(kmsan_poison_shadow); + +void kmsan_unpoison_shadow(const void *address, size_t size) +{ + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + + ENTER_RUNTIME(irq_flags); + /* The users may want to poison/unpoison random memory. */ + kmsan_internal_unpoison_shadow((void *)address, size, + KMSAN_POISON_NOCHECK); + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(kmsan_unpoison_shadow); + +void kmsan_check_memory(const void *addr, size_t size) +{ + return kmsan_internal_check_memory((void *)addr, size, /*user_addr*/ 0, + REASON_ANY); +} +EXPORT_SYMBOL(kmsan_check_memory); + +void kmsan_gup_pgd_range(struct page **pages, int nr) +{ + int i; + void *page_addr; + + /* + * gup_pgd_range() has just created a number of new pages that KMSAN + * treats as uninitialized. In the case they belong to the userspace + * memory, unpoison the corresponding kernel pages. + */ + for (i = 0; i < nr; i++) { + page_addr = page_address(pages[i]); + if (((u64)page_addr < TASK_SIZE) && + ((u64)page_addr + PAGE_SIZE < TASK_SIZE)) + kmsan_unpoison_shadow(page_addr, PAGE_SIZE); + } + +} +EXPORT_SYMBOL(kmsan_gup_pgd_range); + +/* Helper function to check an SKB. */ +void kmsan_check_skb(const struct sk_buff *skb) +{ + int start = skb_headlen(skb); + struct sk_buff *frag_iter; + int i, copy = 0; + skb_frag_t *f; + u32 p_off, p_len, copied; + struct page *p; + u8 *vaddr; + + if (!skb || !skb->len) + return; + + kmsan_internal_check_memory(skb->data, skb_headlen(skb), 0, REASON_ANY); + if (skb_is_nonlinear(skb)) { + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + f = &skb_shinfo(skb)->frags[i]; + + skb_frag_foreach_page(f, + skb_frag_off(f) - start, + copy, p, p_off, p_len, copied) { + + vaddr = kmap_atomic(p); + kmsan_internal_check_memory(vaddr + p_off, + p_len, /*user_addr*/ 0, + REASON_ANY); + kunmap_atomic(vaddr); + } + } + } + skb_walk_frags(skb, frag_iter) + kmsan_check_skb(frag_iter); +} +EXPORT_SYMBOL(kmsan_check_skb); + +/* Helper function to check an URB. */ +void kmsan_handle_urb(const struct urb *urb, bool is_out) +{ + if (!urb) + return; + if (is_out) + kmsan_internal_check_memory(urb->transfer_buffer, + urb->transfer_buffer_length, + /*user_addr*/ 0, REASON_SUBMIT_URB); + else + kmsan_internal_unpoison_shadow(urb->transfer_buffer, + urb->transfer_buffer_length, + /*checked*/false); +} +EXPORT_SYMBOL(kmsan_handle_urb); + +/* Helper function to check I2C-transferred data. */ +void kmsan_handle_i2c_transfer(struct i2c_msg *msgs, int num) +{ + int i; + + if (!msgs) + return; + for (i = 0; i < num; i++) { + if (msgs[i].flags & I2C_M_RD) + kmsan_internal_unpoison_shadow(msgs[i].buf, + msgs[i].len, + /*checked*/false); + else + kmsan_internal_check_memory(msgs[i].buf, msgs[i].len, + /*user_addr*/0, + REASON_ANY); + } +} + +/* + * Helper function to check printk. + * Some optimizations may cause *fmt to be uninitialized, that's why it's + * passed by reference. + */ +void kmsan_handle_vprintk(const char **fmt, va_list args) +{ + unsigned long irq_flags; + size_t fmt_size; + + if (!kmsan_ready || IN_RUNTIME()) + return; + ENTER_RUNTIME(irq_flags); + fmt_size = strlen(*fmt); + LEAVE_RUNTIME(irq_flags); + /* TODO(glider): check |args|. */ + kmsan_internal_check_memory(fmt, sizeof(char *), /*user_addr*/0, + REASON_ANY); + kmsan_internal_check_memory((void *)(*fmt), fmt_size, /*user_addr*/0, + REASON_ANY); +} +EXPORT_SYMBOL(kmsan_handle_vprintk); diff --git a/mm/kmsan/kmsan_init.c b/mm/kmsan/kmsan_init.c new file mode 100644 index 000000000000..606c4b0c90d3 --- /dev/null +++ b/mm/kmsan/kmsan_init.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN initialization routines. + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include "kmsan.h" + +#include +#include +#include + +#define NUM_FUTURE_RANGES 128 +struct start_end_pair { + void *start, *end; +}; + +static struct start_end_pair start_end_pairs[NUM_FUTURE_RANGES] __initdata; +static int future_index __initdata; + +/* + * Record a range of memory for which the metadata pages will be created once + * the page allocator becomes available. + * TODO(glider): squash together ranges belonging to the same page. + */ +static void __init kmsan_record_future_shadow_range(void *start, void *end) +{ + BUG_ON(future_index == NUM_FUTURE_RANGES); + BUG_ON((start >= end) || !start || !end); + start_end_pairs[future_index].start = start; + start_end_pairs[future_index].end = end; + future_index++; +} + +extern char _sdata[], _edata[]; + + + +/* + * Initialize the shadow for existing mappings during kernel initialization. + * These include kernel text/data sections, NODE_DATA and future ranges + * registered while creating other data (e.g. percpu). + * + * Allocations via memblock can be only done before slab is initialized. + */ +void __init kmsan_initialize_shadow(void) +{ + int nid; + u64 i; + const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE); + phys_addr_t p_start, p_end; + + for_each_reserved_mem_region(i, &p_start, &p_end) { + kmsan_record_future_shadow_range(phys_to_virt(p_start), + phys_to_virt(p_end+1)); + } + /* Allocate shadow for .data */ + kmsan_record_future_shadow_range(_sdata, _edata); + + /* + * TODO(glider): alloc_node_data() in arch/x86/mm/numa.c uses + * sizeof(pg_data_t). + */ + for_each_online_node(nid) + kmsan_record_future_shadow_range( + NODE_DATA(nid), (char *)NODE_DATA(nid) + nd_size); + + for (i = 0; i < future_index; i++) + kmsan_init_alloc_meta_for_range(start_end_pairs[i].start, + start_end_pairs[i].end); +} +EXPORT_SYMBOL(kmsan_initialize_shadow); + +void __init kmsan_initialize(void) +{ + /* Assuming current is init_task */ + kmsan_internal_task_create(current); + kmsan_pr_err("Starting KernelMemorySanitizer\n"); + kmsan_ready = true; +} +EXPORT_SYMBOL(kmsan_initialize); diff --git a/mm/kmsan/kmsan_instr.c b/mm/kmsan/kmsan_instr.c new file mode 100644 index 000000000000..74cb7cee7f70 --- /dev/null +++ b/mm/kmsan/kmsan_instr.c @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN compiler API. + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include "kmsan.h" +#include +#include + +static bool is_bad_asm_addr(void *addr, u64 size, bool is_store) +{ + if ((u64)addr < TASK_SIZE) + return true; + if (!kmsan_get_metadata(addr, size, META_SHADOW)) + return true; + return false; +} + +struct shadow_origin_ptr __msan_metadata_ptr_for_load_n(void *addr, u64 size) +{ + return kmsan_get_shadow_origin_ptr(addr, size, /*store*/false); +} +EXPORT_SYMBOL(__msan_metadata_ptr_for_load_n); + +struct shadow_origin_ptr __msan_metadata_ptr_for_store_n(void *addr, u64 size) +{ + return kmsan_get_shadow_origin_ptr(addr, size, /*store*/true); +} +EXPORT_SYMBOL(__msan_metadata_ptr_for_store_n); + +#define DECLARE_METADATA_PTR_GETTER(size) \ +struct shadow_origin_ptr __msan_metadata_ptr_for_load_##size(void *addr) \ +{ \ + return kmsan_get_shadow_origin_ptr(addr, size, /*store*/false); \ +} \ +EXPORT_SYMBOL(__msan_metadata_ptr_for_load_##size); \ + \ +struct shadow_origin_ptr __msan_metadata_ptr_for_store_##size(void *addr) \ +{ \ + return kmsan_get_shadow_origin_ptr(addr, size, /*store*/true); \ +} \ +EXPORT_SYMBOL(__msan_metadata_ptr_for_store_##size) + +DECLARE_METADATA_PTR_GETTER(1); +DECLARE_METADATA_PTR_GETTER(2); +DECLARE_METADATA_PTR_GETTER(4); +DECLARE_METADATA_PTR_GETTER(8); + +void __msan_instrument_asm_store(void *addr, u64 size) +{ + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + /* + * Most of the accesses are below 32 bytes. The two exceptions so far + * are clwb() (64 bytes) and FPU state (512 bytes). + * It's unlikely that the assembly will touch more than 512 bytes. + */ + if (size > 512) + size = 8; + if (is_bad_asm_addr(addr, size, /*is_store*/true)) + return; + ENTER_RUNTIME(irq_flags); + /* Unpoisoning the memory on best effort. */ + kmsan_internal_unpoison_shadow(addr, size, /*checked*/false); + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(__msan_instrument_asm_store); + +void *__msan_memmove(void *dst, void *src, u64 n) +{ + void *result; + void *shadow_dst; + + result = __memmove(dst, src, n); + if (!n) + /* Some people call memmove() with zero length. */ + return result; + if (!kmsan_ready || IN_RUNTIME()) + return result; + + /* Ok to skip address check here, we'll do it later. */ + shadow_dst = kmsan_get_metadata(dst, n, META_SHADOW); + + if (!shadow_dst) + /* Can happen e.g. if the memory is untracked. */ + return result; + + kmsan_memmove_metadata(dst, src, n); + + return result; +} +EXPORT_SYMBOL(__msan_memmove); + +void *__msan_memmove_nosanitize(void *dst, void *src, u64 n) +{ + return __memmove(dst, src, n); +} +EXPORT_SYMBOL(__msan_memmove_nosanitize); + +void *__msan_memcpy(void *dst, const void *src, u64 n) +{ + void *result; + void *shadow_dst; + + result = __memcpy(dst, src, n); + if (!n) + /* Some people call memcpy() with zero length. */ + return result; + + if (!kmsan_ready || IN_RUNTIME()) + return result; + + /* Ok to skip address check here, we'll do it later. */ + shadow_dst = kmsan_get_metadata(dst, n, META_SHADOW); + if (!shadow_dst) + /* Can happen e.g. if the memory is untracked. */ + return result; + + kmsan_memcpy_metadata(dst, (void *)src, n); + + return result; +} +EXPORT_SYMBOL(__msan_memcpy); + +void *__msan_memcpy_nosanitize(void *dst, void *src, u64 n) +{ + return __memcpy(dst, src, n); +} +EXPORT_SYMBOL(__msan_memcpy_nosanitize); + +void *__msan_memset(void *dst, int c, size_t n) +{ + void *result; + unsigned long irq_flags; + depot_stack_handle_t new_origin; + unsigned int shadow; + + result = __memset(dst, c, n); + if (!kmsan_ready || IN_RUNTIME()) + return result; + + ENTER_RUNTIME(irq_flags); + shadow = 0; + kmsan_internal_memset_shadow(dst, shadow, n, /*checked*/false); + new_origin = 0; + kmsan_internal_set_origin(dst, n, new_origin); + LEAVE_RUNTIME(irq_flags); + + return result; +} +EXPORT_SYMBOL(__msan_memset); + +void *__msan_memset_nosanitize(void *dst, int c, size_t n) +{ + return __memset(dst, c, n); +} +EXPORT_SYMBOL(__msan_memset_nosanitize); + +depot_stack_handle_t __msan_chain_origin(depot_stack_handle_t origin) +{ + depot_stack_handle_t ret = 0; + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return ret; + + /* Creating new origins may allocate memory. */ + ENTER_RUNTIME(irq_flags); + ret = kmsan_internal_chain_origin(origin); + LEAVE_RUNTIME(irq_flags); + return ret; +} +EXPORT_SYMBOL(__msan_chain_origin); + +void __msan_poison_alloca(void *address, u64 size, char *descr) +{ + depot_stack_handle_t handle; + unsigned long entries[4]; + unsigned long irq_flags; + u64 size_copy = size, to_fill; + u64 addr_copy = (u64)address; + u64 page_offset; + void *shadow_start; + + if (!kmsan_ready || IN_RUNTIME()) + return; + + while (size_copy) { + page_offset = addr_copy % PAGE_SIZE; + to_fill = min(PAGE_SIZE - page_offset, size_copy); + shadow_start = kmsan_get_metadata((void *)addr_copy, to_fill, + META_SHADOW); + if (!shadow_start) + /* Can happen e.g. if the memory is untracked. */ + continue; + __memset(shadow_start, -1, to_fill); + addr_copy += to_fill; + size_copy -= to_fill; + } + + entries[0] = KMSAN_ALLOCA_MAGIC_ORIGIN; + entries[1] = (u64)descr; + entries[2] = (u64)__builtin_return_address(0); + entries[3] = (u64)kmsan_internal_return_address(1); + + /* stack_depot_save() may allocate memory. */ + ENTER_RUNTIME(irq_flags); + handle = stack_depot_save(entries, ARRAY_SIZE(entries), GFP_ATOMIC); + LEAVE_RUNTIME(irq_flags); + kmsan_internal_set_origin(address, size, handle); +} +EXPORT_SYMBOL(__msan_poison_alloca); + +void __msan_unpoison_alloca(void *address, u64 size) +{ + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + + ENTER_RUNTIME(irq_flags); + /* Assuming the shadow exists. */ + kmsan_internal_unpoison_shadow(address, size, /*checked*/true); + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(__msan_unpoison_alloca); + +void __msan_warning(u32 origin) +{ + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + ENTER_RUNTIME(irq_flags); + kmsan_report(origin, /*address*/0, /*size*/0, + /*off_first*/0, /*off_last*/0, /*user_addr*/0, REASON_ANY); + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(__msan_warning); + +struct kmsan_context_state *__msan_get_context_state(void) +{ + struct kmsan_context_state *ret; + + ret = task_kmsan_context_state(); + BUG_ON(!ret); + return ret; +} +EXPORT_SYMBOL(__msan_get_context_state); diff --git a/mm/kmsan/kmsan_report.c b/mm/kmsan/kmsan_report.c new file mode 100644 index 000000000000..5dddacb8e6d8 --- /dev/null +++ b/mm/kmsan/kmsan_report.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN error reporting routines. + * + * Copyright (C) 2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include + +#include "kmsan.h" + +DEFINE_SPINLOCK(report_lock); + +void kmsan_print_origin(depot_stack_handle_t origin) +{ + unsigned long *entries = NULL, *chained_entries = NULL; + unsigned long nr_entries, chained_nr_entries, magic; + char *descr = NULL; + void *pc1 = NULL, *pc2 = NULL; + depot_stack_handle_t head; + + if (!origin) { + kmsan_pr_err("Origin not found, presumably a false report.\n"); + return; + } + + while (true) { + nr_entries = stack_depot_fetch(origin, &entries); + magic = nr_entries ? (entries[0] & KMSAN_MAGIC_MASK) : 0; + if ((nr_entries == 4) && (magic == KMSAN_ALLOCA_MAGIC_ORIGIN)) { + descr = (char *)entries[1]; + pc1 = (void *)entries[2]; + pc2 = (void *)entries[3]; + kmsan_pr_err("Local variable description: %s\n", descr); + kmsan_pr_err("Variable was created at:\n"); + kmsan_pr_err(" %pS\n", pc1); + kmsan_pr_err(" %pS\n", pc2); + break; + } + if ((nr_entries == 3) && + (magic == KMSAN_CHAIN_MAGIC_ORIGIN_FULL)) { + head = entries[1]; + origin = entries[2]; + kmsan_pr_err("Uninit was stored to memory at:\n"); + chained_nr_entries = + stack_depot_fetch(head, &chained_entries); + stack_trace_print(chained_entries, chained_nr_entries, + 0); + kmsan_pr_err("\n"); + continue; + } + kmsan_pr_err("Uninit was created at:\n"); + if (entries) + stack_trace_print(entries, nr_entries, 0); + else + kmsan_pr_err("No stack\n"); + break; + } +} + +void kmsan_report(depot_stack_handle_t origin, + void *address, int size, int off_first, int off_last, + const void *user_addr, int reason) +{ + unsigned long flags; + unsigned long *entries; + unsigned int nr_entries; + bool is_uaf = false; + char *bug_type = NULL; + + if (!kmsan_ready) + return; + if (!current->kmsan.allow_reporting) + return; + if (this_cpu_read(printk_context) & PRINTK_SAFE_CONTEXT_MASK) + return; + if (!origin) + return; + + nr_entries = stack_depot_fetch(origin, &entries); + + current->kmsan.allow_reporting = false; + spin_lock_irqsave(&report_lock, flags); + kmsan_pr_err("=====================================================\n"); + if (get_dsh_extra_bits(origin) & 1) + is_uaf = true; + switch (reason) { + case REASON_ANY: + bug_type = is_uaf ? "use-after-free" : "uninit-value"; + break; + case REASON_COPY_TO_USER: + bug_type = is_uaf ? "kernel-infoleak-after-free" : + "kernel-infoleak"; + break; + case REASON_SUBMIT_URB: + bug_type = is_uaf ? "kernel-usb-infoleak-after-free" : + "kernel-usb-infoleak"; + break; + } + kmsan_pr_err("BUG: KMSAN: %s in %pS\n", + bug_type, kmsan_internal_return_address(2)); + dump_stack(); + kmsan_pr_err("\n"); + + kmsan_print_origin(origin); + + if (size) { + kmsan_pr_err("\n"); + if (off_first == off_last) + kmsan_pr_err("Byte %d of %d is uninitialized\n", + off_first, size); + else + kmsan_pr_err("Bytes %d-%d of %d are uninitialized\n", + off_first, off_last, size); + } + if (address) + kmsan_pr_err("Memory access of size %d starts at %px\n", + size, address); + if (user_addr && reason == REASON_COPY_TO_USER) + kmsan_pr_err("Data copied to user address %px\n", user_addr); + kmsan_pr_err("=====================================================\n"); + add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); + spin_unlock_irqrestore(&report_lock, flags); + if (panic_on_warn) + panic("panic_on_warn set ...\n"); + current->kmsan.allow_reporting = true; +} diff --git a/mm/kmsan/kmsan_shadow.c b/mm/kmsan/kmsan_shadow.c new file mode 100644 index 000000000000..06801d76e6b8 --- /dev/null +++ b/mm/kmsan/kmsan_shadow.c @@ -0,0 +1,543 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KMSAN shadow implementation. + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kmsan.h" +#include "kmsan_shadow.h" + +#define shadow_page_for(page) \ + ((page)->shadow) + +#define origin_page_for(page) \ + ((page)->origin) + +#define shadow_ptr_for(page) \ + (page_address((page)->shadow)) + +#define origin_ptr_for(page) \ + (page_address((page)->origin)) + +#define has_shadow_page(page) \ + (!!((page)->shadow)) + +#define has_origin_page(page) \ + (!!((page)->origin)) + +#define set_no_shadow_origin_page(page) \ + do { \ + (page)->shadow = NULL; \ + (page)->origin = NULL; \ + } while (0) /**/ + +#define is_ignored_page(page) \ + (!!(((u64)((page)->shadow)) % 2)) + +#define ignore_page(pg) \ + ((pg)->shadow = (struct page *)((u64)((pg)->shadow) | 1)) \ + +DEFINE_PER_CPU(char[CPU_ENTRY_AREA_SIZE], cpu_entry_area_shadow); +DEFINE_PER_CPU(char[CPU_ENTRY_AREA_SIZE], cpu_entry_area_origin); + +/* + * Dummy load and store pages to be used when the real metadata is unavailable. + * There are separate pages for loads and stores, so that every load returns a + * zero, and every store doesn't affect other stores. + */ +char dummy_load_page[PAGE_SIZE] __aligned(PAGE_SIZE); +char dummy_store_page[PAGE_SIZE] __aligned(PAGE_SIZE); + +/* + * Taken from arch/x86/mm/physaddr.h to avoid using an instrumented version. + */ +static int kmsan_phys_addr_valid(unsigned long addr) +{ +#ifdef CONFIG_PHYS_ADDR_T_64BIT + return !(addr >> boot_cpu_data.x86_phys_bits); +#else + return 1; +#endif +} + +/* + * Taken from arch/x86/mm/physaddr.c to avoid using an instrumented version. + */ +static bool kmsan_virt_addr_valid(void *addr) +{ + unsigned long x = (unsigned long)addr; + unsigned long y = x - __START_KERNEL_map; + + /* use the carry flag to determine if x was < __START_KERNEL_map */ + if (unlikely(x > y)) { + x = y + phys_base; + + if (y >= KERNEL_IMAGE_SIZE) + return false; + } else { + x = y + (__START_KERNEL_map - PAGE_OFFSET); + + /* carry flag will be set if starting x was >= PAGE_OFFSET */ + if ((x > y) || !kmsan_phys_addr_valid(x)) + return false; + } + + return pfn_valid(x >> PAGE_SHIFT); +} + +static unsigned long vmalloc_meta(void *addr, bool is_origin) +{ + unsigned long addr64 = (unsigned long)addr, off; + + BUG_ON(is_origin && !IS_ALIGNED(addr64, ORIGIN_SIZE)); + if (kmsan_internal_is_vmalloc_addr(addr)) { + return addr64 + (is_origin ? VMALLOC_ORIGIN_OFFSET + : VMALLOC_SHADOW_OFFSET); + } + if (kmsan_internal_is_module_addr(addr)) { + off = addr64 - MODULES_VADDR; + return off + (is_origin ? MODULES_ORIGIN_START + : MODULES_SHADOW_START); + } + return 0; +} + +static void *get_cea_meta_or_null(void *addr, bool is_origin) +{ + int cpu = smp_processor_id(); + int off; + char *metadata_array; + + if (((u64)addr < CPU_ENTRY_AREA_BASE) || + ((u64)addr >= (CPU_ENTRY_AREA_BASE + CPU_ENTRY_AREA_MAP_SIZE))) + return NULL; + off = (char *)addr - (char *)get_cpu_entry_area(cpu); + if ((off < 0) || (off >= CPU_ENTRY_AREA_SIZE)) + return NULL; + metadata_array = is_origin ? cpu_entry_area_origin : + cpu_entry_area_shadow; + return &per_cpu(metadata_array[off], cpu); +} + +static struct page *virt_to_page_or_null(void *vaddr) +{ + if (kmsan_virt_addr_valid(vaddr)) + return virt_to_page(vaddr); + else + return NULL; +} + +struct shadow_origin_ptr kmsan_get_shadow_origin_ptr(void *address, u64 size, + bool store) +{ + struct shadow_origin_ptr ret; + struct page *page; + u64 pad, offset, o_offset; + const u64 addr64 = (u64)address; + u64 o_addr64 = (u64)address; + void *shadow; + + if (size > PAGE_SIZE) { + WARN(1, "size too big in %s(%px, %d, %d)\n", + __func__, address, size, store); + BUG(); + } + if (store) { + ret.s = dummy_store_page; + ret.o = dummy_store_page; + } else { + ret.s = dummy_load_page; + ret.o = dummy_load_page; + } + if (!kmsan_ready || IN_RUNTIME()) + return ret; + BUG_ON(!metadata_is_contiguous(address, size, META_SHADOW)); + + if (!IS_ALIGNED(addr64, ORIGIN_SIZE)) { + pad = addr64 % ORIGIN_SIZE; + o_addr64 -= pad; + } + + if (kmsan_internal_is_vmalloc_addr(address) || + kmsan_internal_is_module_addr(address)) { + ret.s = (void *)vmalloc_meta(address, META_SHADOW); + ret.o = (void *)vmalloc_meta((void *)o_addr64, META_ORIGIN); + return ret; + } + + if (!kmsan_virt_addr_valid(address)) { + page = vmalloc_to_page_or_null(address); + if (page) + goto next; + shadow = get_cea_meta_or_null(address, META_SHADOW); + if (shadow) { + ret.s = shadow; + ret.o = get_cea_meta_or_null((void *)o_addr64, + META_ORIGIN); + return ret; + } + } + page = virt_to_page_or_null(address); + if (!page) + return ret; +next: + if (is_ignored_page(page)) + return ret; + + if (!has_shadow_page(page) || !has_origin_page(page)) + return ret; + offset = addr64 % PAGE_SIZE; + o_offset = o_addr64 % PAGE_SIZE; + + if (offset + size - 1 > PAGE_SIZE) { + /* + * The access overflows the current page and touches the + * subsequent ones. Make sure the shadow/origin pages are also + * consequent. + */ + BUG_ON(!metadata_is_contiguous(address, size, META_SHADOW)); + } + + ret.s = shadow_ptr_for(page) + offset; + ret.o = origin_ptr_for(page) + o_offset; + return ret; +} + +/* + * Obtain the shadow or origin pointer for the given address, or NULL if there's + * none. The caller must check the return value for being non-NULL if needed. + * The return value of this function should not depend on whether we're in the + * runtime or not. + */ +void *kmsan_get_metadata(void *address, size_t size, bool is_origin) +{ + struct page *page; + void *ret; + u64 addr = (u64)address, pad, off; + + if (is_origin && !IS_ALIGNED(addr, ORIGIN_SIZE)) { + pad = addr % ORIGIN_SIZE; + addr -= pad; + size += pad; + } + address = (void *)addr; + if (kmsan_internal_is_vmalloc_addr(address) || + kmsan_internal_is_module_addr(address)) { + return (void *)vmalloc_meta(address, is_origin); + } + + if (!kmsan_virt_addr_valid(address)) { + page = vmalloc_to_page_or_null(address); + if (page) + goto next; + ret = get_cea_meta_or_null(address, is_origin); + if (ret) + return ret; + } + page = virt_to_page_or_null(address); + if (!page) + return NULL; +next: + if (is_ignored_page(page)) + return NULL; + if (!has_shadow_page(page) || !has_origin_page(page)) + return NULL; + off = addr % PAGE_SIZE; + + ret = (is_origin ? origin_ptr_for(page) : shadow_ptr_for(page)) + off; + return ret; +} + +void __init kmsan_init_alloc_meta_for_range(void *start, void *end) +{ + u64 addr, size; + struct page *page; + void *shadow, *origin; + struct page *shadow_p, *origin_p; + + start = (void *)ALIGN_DOWN((u64)start, PAGE_SIZE); + size = ALIGN((u64)end - (u64)start, PAGE_SIZE); + shadow = memblock_alloc(size, PAGE_SIZE); + origin = memblock_alloc(size, PAGE_SIZE); + for (addr = 0; addr < size; addr += PAGE_SIZE) { + page = virt_to_page_or_null((char *)start + addr); + shadow_p = virt_to_page_or_null((char *)shadow + addr); + set_no_shadow_origin_page(shadow_p); + shadow_page_for(page) = shadow_p; + origin_p = virt_to_page_or_null((char *)origin + addr); + set_no_shadow_origin_page(origin_p); + origin_page_for(page) = origin_p; + } +} + +/* Called from mm/memory.c */ +void kmsan_copy_page_meta(struct page *dst, struct page *src) +{ + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + if (!has_shadow_page(src)) { + /* TODO(glider): are we leaking pages here? */ + set_no_shadow_origin_page(dst); + return; + } + if (!has_shadow_page(dst)) + return; + if (is_ignored_page(src)) { + ignore_page(dst); + return; + } + + ENTER_RUNTIME(irq_flags); + __memcpy(shadow_ptr_for(dst), shadow_ptr_for(src), + PAGE_SIZE); + BUG_ON(!has_origin_page(src) || !has_origin_page(dst)); + __memcpy(origin_ptr_for(dst), origin_ptr_for(src), + PAGE_SIZE); + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(kmsan_copy_page_meta); + +/* Helper function to allocate page metadata. */ +static int kmsan_internal_alloc_meta_for_pages(struct page *page, + unsigned int order, + gfp_t flags, int node) +{ + struct page *shadow, *origin; + int pages = 1 << order; + int i; + bool initialized = (flags & __GFP_ZERO) || !kmsan_ready; + depot_stack_handle_t handle; + + if (flags & __GFP_NO_KMSAN_SHADOW) { + for (i = 0; i < pages; i++) + set_no_shadow_origin_page(&page[i]); + return 0; + } + + /* TODO(glider): must we override the flags? */ + flags = GFP_ATOMIC; + if (initialized) + flags |= __GFP_ZERO; + shadow = alloc_pages_node(node, flags | __GFP_NO_KMSAN_SHADOW, order); + if (!shadow) { + for (i = 0; i < pages; i++) { + set_no_shadow_origin_page(&page[i]); + set_no_shadow_origin_page(&page[i]); + } + return -ENOMEM; + } + if (!initialized) + __memset(page_address(shadow), -1, PAGE_SIZE * pages); + + origin = alloc_pages_node(node, flags | __GFP_NO_KMSAN_SHADOW, order); + /* Assume we've allocated the origin. */ + if (!origin) { + __free_pages(shadow, order); + for (i = 0; i < pages; i++) + set_no_shadow_origin_page(&page[i]); + return -ENOMEM; + } + + if (!initialized) { + handle = kmsan_save_stack_with_flags(flags, /*extra_bits*/0); + /* + * Addresses are page-aligned, pages are contiguous, so it's ok + * to just fill the origin pages with |handle|. + */ + for (i = 0; i < PAGE_SIZE * pages / sizeof(handle); i++) { + ((depot_stack_handle_t *)page_address(origin))[i] = + handle; + } + } + + for (i = 0; i < pages; i++) { + shadow_page_for(&page[i]) = &shadow[i]; + set_no_shadow_origin_page(shadow_page_for(&page[i])); + origin_page_for(&page[i]) = &origin[i]; + set_no_shadow_origin_page(origin_page_for(&page[i])); + } + return 0; +} + +/* Called from mm/page_alloc.c */ +int kmsan_alloc_page(struct page *page, unsigned int order, gfp_t flags) +{ + unsigned long irq_flags; + int ret; + + if (IN_RUNTIME()) + return 0; + ENTER_RUNTIME(irq_flags); + ret = kmsan_internal_alloc_meta_for_pages(page, order, flags, -1); + LEAVE_RUNTIME(irq_flags); + return ret; +} + +/* Called from mm/page_alloc.c */ +void kmsan_free_page(struct page *page, unsigned int order) +{ + struct page *shadow, *origin, *cur_page; + int pages = 1 << order; + int i; + unsigned long irq_flags; + + if (!shadow_page_for(page)) { + for (i = 0; i < pages; i++) { + cur_page = &page[i]; + BUG_ON(shadow_page_for(cur_page)); + } + return; + } + + if (!kmsan_ready) { + for (i = 0; i < pages; i++) { + cur_page = &page[i]; + set_no_shadow_origin_page(cur_page); + } + return; + } + + if (IN_RUNTIME()) { + /* + * TODO(glider): looks legit. depot_save_stack() may call + * free_pages(). + */ + return; + } + + ENTER_RUNTIME(irq_flags); + shadow = shadow_page_for(&page[0]); + origin = origin_page_for(&page[0]); + + /* TODO(glider): this is racy. */ + for (i = 0; i < pages; i++) { + BUG_ON(has_shadow_page(shadow_page_for(&page[i]))); + BUG_ON(has_shadow_page(origin_page_for(&page[i]))); + set_no_shadow_origin_page(&page[i]); + } + BUG_ON(has_shadow_page(shadow)); + __free_pages(shadow, order); + + BUG_ON(has_shadow_page(origin)); + __free_pages(origin, order); + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(kmsan_free_page); + +/* Called from mm/page_alloc.c */ +void kmsan_split_page(struct page *page, unsigned int order) +{ + struct page *shadow, *origin; + unsigned long irq_flags; + + if (!kmsan_ready || IN_RUNTIME()) + return; + + ENTER_RUNTIME(irq_flags); + if (!has_shadow_page(&page[0])) { + BUG_ON(has_origin_page(&page[0])); + LEAVE_RUNTIME(irq_flags); + return; + } + shadow = shadow_page_for(&page[0]); + split_page(shadow, order); + + origin = origin_page_for(&page[0]); + split_page(origin, order); + LEAVE_RUNTIME(irq_flags); +} +EXPORT_SYMBOL(kmsan_split_page); + +/* Called from include/linux/highmem.h */ +void kmsan_clear_page(void *page_addr) +{ + struct page *page; + + if (!kmsan_ready || IN_RUNTIME()) + return; + BUG_ON(!IS_ALIGNED((u64)page_addr, PAGE_SIZE)); + page = vmalloc_to_page_or_null(page_addr); + if (!page) + page = virt_to_page_or_null(page_addr); + if (!page || !has_shadow_page(page)) + return; + __memset(shadow_ptr_for(page), 0, PAGE_SIZE); + BUG_ON(!has_origin_page(page)); + __memset(origin_ptr_for(page), 0, PAGE_SIZE); +} +EXPORT_SYMBOL(kmsan_clear_page); + +/* Called from mm/vmalloc.c */ +void kmsan_vmap_page_range_noflush(unsigned long start, unsigned long end, + pgprot_t prot, struct page **pages) +{ + int nr, i, mapped; + struct page **s_pages, **o_pages; + unsigned long shadow_start, shadow_end, origin_start, origin_end; + + if (!kmsan_ready || IN_RUNTIME()) + return; + shadow_start = vmalloc_meta((void *)start, META_SHADOW); + if (!shadow_start) + return; + + BUG_ON(start >= end); + nr = (end - start) / PAGE_SIZE; + s_pages = kcalloc(nr, sizeof(struct page *), GFP_KERNEL); + o_pages = kcalloc(nr, sizeof(struct page *), GFP_KERNEL); + if (!s_pages || !o_pages) + goto ret; + for (i = 0; i < nr; i++) { + s_pages[i] = shadow_page_for(pages[i]); + o_pages[i] = origin_page_for(pages[i]); + } + prot = __pgprot(pgprot_val(prot) | _PAGE_NX); + prot = PAGE_KERNEL; + + shadow_end = vmalloc_meta((void *)end, META_SHADOW); + origin_start = vmalloc_meta((void *)start, META_ORIGIN); + origin_end = vmalloc_meta((void *)end, META_ORIGIN); + mapped = __vmap_page_range_noflush(shadow_start, shadow_end, + prot, s_pages); + BUG_ON(mapped != nr); + flush_tlb_kernel_range(shadow_start, shadow_end); + mapped = __vmap_page_range_noflush(origin_start, origin_end, + prot, o_pages); + BUG_ON(mapped != nr); + flush_tlb_kernel_range(origin_start, origin_end); +ret: + kfree(s_pages); + kfree(o_pages); +} + +void kmsan_ignore_page(struct page *page, int order) +{ + int pages = 1 << order; + int i; + struct page *cp; + + for (i = 0; i < pages; i++) { + cp = &page[i]; + ignore_page(cp); + } +} diff --git a/mm/kmsan/kmsan_shadow.h b/mm/kmsan/kmsan_shadow.h new file mode 100644 index 000000000000..eaa7f771b6a5 --- /dev/null +++ b/mm/kmsan/kmsan_shadow.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * KMSAN shadow API. + * + * This should be agnostic to shadow implementation details. + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __MM_KMSAN_KMSAN_SHADOW_H +#define __MM_KMSAN_KMSAN_SHADOW_H + +#include /* for CPU_ENTRY_AREA_MAP_SIZE */ + +struct shadow_origin_ptr { + void *s, *o; +}; + +struct shadow_origin_ptr kmsan_get_shadow_origin_ptr(void *addr, u64 size, + bool store); +void *kmsan_get_metadata(void *addr, size_t size, bool is_origin); +void __init kmsan_init_alloc_meta_for_range(void *start, void *end); + +#endif /* __MM_KMSAN_KMSAN_SHADOW_H */ diff --git a/scripts/Makefile.kmsan b/scripts/Makefile.kmsan new file mode 100644 index 000000000000..8b3844b66b22 --- /dev/null +++ b/scripts/Makefile.kmsan @@ -0,0 +1,12 @@ +ifdef CONFIG_KMSAN + +CFLAGS_KMSAN := -fsanitize=kernel-memory + +ifeq ($(call cc-option, $(CFLAGS_KMSAN) -Werror),) + ifneq ($(CONFIG_COMPILE_TEST),y) + $(warning Cannot use CONFIG_KMSAN: \ + -fsanitize=kernel-memory is not supported by compiler) + endif +endif + +endif From patchwork Fri Oct 18 09:42:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197989 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A35C13B1 for ; Fri, 18 Oct 2019 09:43:55 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id C155E20820 for ; Fri, 18 Oct 2019 09:43:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="nuekFE8N" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C155E20820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id B15898E0027; Fri, 18 Oct 2019 05:43:50 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id AC53B8E0003; Fri, 18 Oct 2019 05:43:50 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9DB5E8E0027; Fri, 18 Oct 2019 05:43:50 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0239.hostedemail.com [216.40.44.239]) by kanga.kvack.org (Postfix) with ESMTP id 7E1FB8E0003 for ; Fri, 18 Oct 2019 05:43:50 -0400 (EDT) Received: from smtpin14.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with SMTP id 1E54C182104A5 for ; Fri, 18 Oct 2019 09:43:50 +0000 (UTC) X-FDA: 76056418620.14.game20_78be7550cb935 X-Spam-Summary: 2,0,0,fc59c698a1426a01,d41d8cd98f00b204,3vimpxqykcaehmjefshpphmf.dpnmjovy-nnlwbdl.psh@flex--glider.bounces.google.com,:glider@google.com:mingo@elte.hu:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:2393:2559:2562:3138:3139:3140:3141:3142:3152:3352:3867:3868:3870:4321:5007:6117:6120:6261:6653:7901:7903:9969:10004:10400:11026:11232:11473:11658:11914:12043:12291:12296:12297:12438:12555:12895:12986:13069:13311:13357:13846:14096:14097:14181:14394:14659:14721:21080:21365:21444:21451:21627:30003:30054:30064,0,RBL:209.85.128.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: game20_78be7550cb935 X-Filterd-Recvd-Size: 4422 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf36.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:49 +0000 (UTC) Received: by mail-wm1-f73.google.com with SMTP id o188so2452151wmo.5 for ; Fri, 18 Oct 2019 02:43:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=UyV9UR3LSpLQrFqhYzhcJbdZOsxELV3pBAp6RXWOa7k=; b=nuekFE8NI08HFbaYwWh3SycyjxIzp03Mx5bY8k4gHVPzYVSLs6UqzpCRKYQkvas4eq FKgX+D8bk/Of+fgG/9/IZxBEl5y5k6yN2WzlHLmRmCTd3+5lHnJkbu59Wq1mJN2YK18D m24XMZED6eQ1PwnZqdAleTBmJkTaCd9PAS1EEk4vzMJY2KKcot4C6iHnk/+RR7hkOVEF X0cLINnUkFQQi4EtxZO0MucbJrqup0/11qmncJAccl07I0ZYMMGY0XI3iCGSIg2udrGi iF/iKGyEk7th19EAFZfq5iqEYEayivCf36LdyqUg177yttPshj2i0TEcSJitYSdNN8jy 1KHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=UyV9UR3LSpLQrFqhYzhcJbdZOsxELV3pBAp6RXWOa7k=; b=MDTHIO0szGeNxT0T92GTaQ1T5+8h7++sRTjaZ2f0AVileek+3/kHRR6N5EuCkw5FZb fbD/MqaA+XehNgFVnpcFnFu6Sp9/JoqnSrJNFwS1pu+4lJi2Xmh5Sembn6qYHf7mip8i 3iyraOODBTIZfnXp3TGqWIuB0LcZ9d2Tig3fpfWz79RugQ2P+MB3ZITRwW5Mnk8XMNEf faAeCAeueIIj62qh83mR/vt65Qn+Q3YWZmUSzs2FB3hxXHxr2rRdLRa/KIWCr0A7lH9D aXNR0OGZaSZt2zxZBTXMMAt6J6WAwT7FnDRC5WE/P6pQysCAjnCYJ4HuW3Gw77ODt6UA XV0w== X-Gm-Message-State: APjAAAVG7kEz4ZV9wax1MBDoRUxQcnNqSr/hnrnSi4ZVHHNU3zWcNht6 7KUl+j522kzcCKjV4Yol5wsF+gs+S4s= X-Google-Smtp-Source: APXvYqzbCCCughfRa7/mYFrp+3qLZvFtcCK9hWbc1RX8vi+ZW6rBkDy/x/eUWhICdA4XWlIZ42xohifdJvM= X-Received: by 2002:a5d:5052:: with SMTP id h18mr7361494wrt.143.1571391828470; Fri, 18 Oct 2019 02:43:48 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:50 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-13-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 12/26] kmsan: x86: sync metadata pages on page fault From: glider@google.com To: Alexander Potapenko Cc: Ingo Molnar , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: KMSAN assumes shadow and origin pages for every allocated page are accessible. For pages in vmalloc region those metadata pages reside in [VMALLOC_END, VMALLOC_META_END), therefore we must sync a bigger memory region. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Ingo Molnar Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I0d54855489870ef1180b37fe2120b601da464bf7 --- arch/x86/mm/fault.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 9ceacd1156db..d582337ba45d 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -320,7 +320,17 @@ static void dump_pagetable(unsigned long address) void vmalloc_sync_all(void) { +#ifdef CONFIG_KMSAN + /* + * For KMSAN, make sure metadata pages for vmalloc area and modules are + * also synced. + */ + sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_META_END); + sync_global_pgds(MODULES_SHADOW_START & PGDIR_MASK, + MODULES_ORIGIN_END); +#else sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END); +#endif } /* @@ -337,7 +347,17 @@ static noinline int vmalloc_fault(unsigned long address) pte_t *pte; /* Make sure we are in vmalloc area: */ +#ifdef CONFIG_KMSAN + /* + * For KMSAN, make sure metadata pages for vmalloc area and modules are + * also synced. + */ + if (!(address >= VMALLOC_START && address < VMALLOC_META_END) && + !(address >= MODULES_SHADOW_START && + address < MODULES_ORIGIN_END)) +#else if (!(address >= VMALLOC_START && address < VMALLOC_END)) +#endif return -1; /* From patchwork Fri Oct 18 09:42:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197991 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C71E614ED for ; Fri, 18 Oct 2019 09:43:57 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 8A66820820 for ; Fri, 18 Oct 2019 09:43:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="s/0DMqth" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8A66820820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 3EA918E0028; Fri, 18 Oct 2019 05:43:53 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 3740E8E0003; Fri, 18 Oct 2019 05:43:53 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 239948E0028; Fri, 18 Oct 2019 05:43:53 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0003.hostedemail.com [216.40.44.3]) by kanga.kvack.org (Postfix) with ESMTP id F3FC58E0003 for ; Fri, 18 Oct 2019 05:43:52 -0400 (EDT) Received: from smtpin01.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with SMTP id A53D518253E07 for ; Fri, 18 Oct 2019 09:43:52 +0000 (UTC) X-FDA: 76056418704.01.army90_791d256b2365b X-Spam-Summary: 2,0,0,ba77070058caf69d,d41d8cd98f00b204,3v4mpxqykcaqkpmhivksskpi.gsqpmry1-qqozego.svk@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:2:41:69:152:355:379:541:800:960:966:973:988:989:1042:1260:1277:1313:1314:1345:1359:1437:1516:1518:1535:1593:1594:1605:1730:1747:1777:1792:2196:2199:2393:2538:2553:2559:2562:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:3872:3873:3874:4049:4120:4250:4321:4385:5007:6119:6120:6261:6653:7901:7903:7904:8660:9969:10004:11026:11232:11473:11658:11914:12043:12291:12294:12295:12296:12297:12438:12555:12683:12895:12986:13148:13161:13229:13230:13846:14394:14659:21080:21365:21444:21451:21627:21740:21772:30054:30056:30064:30067:30070:30090,0,RBL:209.85.222.201:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:24,LUA_ SUMMARY: X-HE-Tag: army90_791d256b2365b X-Filterd-Recvd-Size: 9028 Received: from mail-qk1-f201.google.com (mail-qk1-f201.google.com [209.85.222.201]) by imf47.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:52 +0000 (UTC) Received: by mail-qk1-f201.google.com with SMTP id o133so5019467qke.4 for ; Fri, 18 Oct 2019 02:43:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=p9HVcKssM0/JxHv7Ium7oVkbT6/yYco02v9RVD8kuHk=; b=s/0DMqthBE1YsHpcsljNveryfBffnFauhbA8NMOnU9byJE/kpMBEn8zPa6VB3jCL3F c4xRvOBP+QjG8HfWlv3Dbhk4fS6/y2bTop74tPG1uyN2CPca8D8JUl2BCM8Fi+sLo73R M67QLEqFZMSYXQeUl50CkxlAFgBiHODloHrXzB+VEaXJQeLLbFARZeb1EoU84zKof3N7 r5iU2tuAGEJvzfYQoBhLzVDkQbdxFxKoRnfFbjwzQaGg303s8v6HuUP2cWaiqMrE2Yb+ g4spl54PtLAaeWCLF0e/2PkC4rvC8L0N3Z+hf2ptL33RGu2LShWZW+tTBnWK7nZpMCax j5iA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=p9HVcKssM0/JxHv7Ium7oVkbT6/yYco02v9RVD8kuHk=; b=aXvuRr9dMNZ+g5gcbNd1O08gKc6xEX9xf1YUugaWxH2y2/t7GuOwDm8+5EcruK9JT7 GclwVCGt5aZ0SPEoiZYZhA6m/iedoto335qflj+J7u/hU1cP/RazjsjuH6sMhQiHl79h 02mR7QvN5C8hUipSF0Hycc4iYtaq2opSdSE1kGKktim4WZdrMzv0hrtyitsJqcqp1nju 36Mn/gtDaUBF8TYXmwExorP2iSRZBBIYzmSgcmT4QLVcTtYL8itFVWpTLMzFl4qO/ZW8 kqZcAKDZTHSphIK3gufGCpIx85hZoxoZdrQSVhHxF4S9qUHoQZ+dI45/2sddCPpxclXy EtGw== X-Gm-Message-State: APjAAAWonkUIft6E6aBcNZXV9BWO/WzJjKf6+bUXLJTvRRAwobDrL6Ip a8bLxDk6X1KmB+NKQ3Lu50/v37hwWu4= X-Google-Smtp-Source: APXvYqyx451t+EiqYgnYURj2Db3o4R25SHcg/Wb4iJ24zFPy0f4LLHBzHzNT2pRa1UD8HZxS9Fq3llS2Txo= X-Received: by 2002:a37:4ac8:: with SMTP id x191mr7995192qka.85.1571391831539; Fri, 18 Oct 2019 02:43:51 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:51 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-14-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 13/26] kmsan: add tests for KMSAN From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: The initial commit adds several tests that trigger KMSAN warnings in simple cases. To use, build the kernel with CONFIG_TEST_KMSAN and do `insmod test_kmsan.ko` Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I287e86ae83a82b770f2baa46e5bbdce1dfa65195 --- lib/Makefile | 1 + lib/test_kmsan.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 lib/test_kmsan.c diff --git a/lib/Makefile b/lib/Makefile index c5892807e06f..cb44262c38ee 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -65,6 +65,7 @@ CFLAGS_test_kasan.o += $(call cc-disable-warning, vla) obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o CFLAGS_test_ubsan.o += $(call cc-disable-warning, vla) UBSAN_SANITIZE_test_ubsan.o := y +obj-$(CONFIG_TEST_KMSAN) += test_kmsan.o obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o obj-$(CONFIG_TEST_LIST_SORT) += test_list_sort.o obj-$(CONFIG_TEST_LKM) += test_module.o diff --git a/lib/test_kmsan.c b/lib/test_kmsan.c new file mode 100644 index 000000000000..97051444c6c4 --- /dev/null +++ b/lib/test_kmsan.c @@ -0,0 +1,221 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Module for testing KMSAN. + * + * Copyright (C) 2017-2019 Google LLC + * Author: Alexander Potapenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +/* + * Tests below use noinline and volatile to work around compiler optimizations + * that may mask KMSAN bugs. + */ +#define pr_fmt(fmt) "kmsan test: %s : " fmt, __func__ + +#include +#include +#include +#include +#include + +#define CHECK(x) \ + do { \ + if (x) \ + pr_info(#x " is true\n"); \ + else \ + pr_info(#x " is false\n"); \ + } while (0) + +noinline void use_integer(int cond) +{ + CHECK(cond); +} + +int signed_sum3(int a, int b, int c) +{ + return a + b + c; +} + +noinline void uninit_kmalloc_test(void) +{ + int *ptr; + + pr_info("-----------------------------\n"); + pr_info("uninitialized kmalloc test (UMR report)\n"); + ptr = kmalloc(sizeof(int), GFP_KERNEL); + pr_info("kmalloc returned %p\n", ptr); + CHECK(*ptr); +} +noinline void init_kmalloc_test(void) +{ + int *ptr; + + pr_info("-----------------------------\n"); + pr_info("initialized kmalloc test (no reports)\n"); + ptr = kmalloc(sizeof(int), GFP_KERNEL); + memset(ptr, 0, sizeof(int)); + pr_info("kmalloc returned %p\n", ptr); + CHECK(*ptr); +} + +noinline void init_kzalloc_test(void) +{ + int *ptr; + + pr_info("-----------------------------\n"); + pr_info("initialized kzalloc test (no reports)\n"); + ptr = kzalloc(sizeof(int), GFP_KERNEL); + pr_info("kzalloc returned %p\n", ptr); + CHECK(*ptr); +} + +noinline void uninit_multiple_args_test(void) +{ + volatile int a; + volatile char b = 3, c; + + pr_info("-----------------------------\n"); + pr_info("uninitialized local passed to fn (UMR report)\n"); + CHECK(signed_sum3(a, b, c)); +} + +noinline void uninit_stack_var_test(void) +{ + int cond; + + pr_info("-----------------------------\n"); + pr_info("uninitialized stack variable (UMR report)\n"); + CHECK(cond); +} + +noinline void init_stack_var_test(void) +{ + volatile int cond = 1; + + pr_info("-----------------------------\n"); + pr_info("initialized stack variable (no reports)\n"); + CHECK(cond); +} + +noinline void two_param_fn_2(int arg1, int arg2) +{ + CHECK(arg1); + CHECK(arg2); +} + +noinline void one_param_fn(int arg) +{ + two_param_fn_2(arg, arg); + CHECK(arg); +} + +noinline void two_param_fn(int arg1, int arg2) +{ + int init = 0; + + one_param_fn(init); + CHECK(arg1); + CHECK(arg2); +} + +void params_test(void) +{ + int uninit, init = 1; + + two_param_fn(uninit, init); +} + +noinline void do_uninit_local_array(char *array, int start, int stop) +{ + int i; + volatile char uninit; + + for (i = start; i < stop; i++) + array[i] = uninit; +} + +noinline void uninit_kmsan_check_memory_test(void) +{ + volatile char local_array[8]; + + pr_info("-----------------------------\n"); + pr_info("kmsan_check_memory() called on uninit local (UMR report)\n"); + do_uninit_local_array((char *)local_array, 5, 7); + + kmsan_check_memory((char *)local_array, 8); +} + +noinline void init_kmsan_vmap_vunmap_test(void) +{ + const int npages = 2; + struct page *pages[npages]; + void *vbuf; + int i; + + pr_info("-----------------------------\n"); + pr_info("pages initialized via vmap (no reports)\n"); + + for (i = 0; i < npages; i++) + pages[i] = alloc_page(GFP_KERNEL); + vbuf = vmap(pages, npages, VM_MAP, PAGE_KERNEL); + memset(vbuf, 0xfe, npages * PAGE_SIZE); + for (i = 0; i < npages; i++) + kmsan_check_memory(page_address(pages[i]), PAGE_SIZE); + + if (vbuf) + vunmap(vbuf); + for (i = 0; i < npages; i++) + if (pages[i]) + __free_page(pages[i]); +} + +noinline void init_vmalloc(void) +{ + char *buf; + int npages = 8, i; + + pr_info("-----------------------------\n"); + pr_info("pages initialized via vmap (no reports)\n"); + buf = vmalloc(PAGE_SIZE * npages); + buf[0] = 1; + memset(buf, 0xfe, PAGE_SIZE * npages); + CHECK(buf[0]); + for (i = 0; i < npages; i++) + kmsan_check_memory(&buf[PAGE_SIZE * i], PAGE_SIZE); + vfree(buf); +} + +noinline void uaf_test(void) +{ + volatile int *var; + + pr_info("-----------------------------\n"); + pr_info("use-after-free in kmalloc-ed buffer (UMR report)\n"); + var = kmalloc(80, GFP_KERNEL); + var[3] = 0xfeedface; + kfree((int *)var); + CHECK(var[3]); +} + +static noinline int __init kmsan_tests_init(void) +{ + uninit_kmalloc_test(); + init_kmalloc_test(); + init_kzalloc_test(); + uninit_multiple_args_test(); + uninit_stack_var_test(); + init_stack_var_test(); + uninit_kmsan_check_memory_test(); + init_kmsan_vmap_vunmap_test(); + init_vmalloc(); + uaf_test(); + return -EAGAIN; +} + +module_init(kmsan_tests_init); +MODULE_LICENSE("GPL"); From patchwork Fri Oct 18 09:42:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197993 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 60A5614ED for ; Fri, 18 Oct 2019 09:44:00 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 233AC20820 for ; Fri, 18 Oct 2019 09:44:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Ic4WoERO" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 233AC20820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 9B66E8E0029; Fri, 18 Oct 2019 05:43:56 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 93DFB8E0003; Fri, 18 Oct 2019 05:43:56 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 80BDA8E0029; Fri, 18 Oct 2019 05:43:56 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0216.hostedemail.com [216.40.44.216]) by kanga.kvack.org (Postfix) with ESMTP id 4C01E8E0003 for ; Fri, 18 Oct 2019 05:43:56 -0400 (EDT) Received: from smtpin23.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with SMTP id DDDB482DF883 for ; Fri, 18 Oct 2019 09:43:55 +0000 (UTC) X-FDA: 76056418830.23.bulb25_79966a74cdf17 X-Spam-Summary: 2,0,0,aa52a0b0f57ec901,d41d8cd98f00b204,3wompxqykcacnspklynvvnsl.jvtspu14-ttr2hjr.vyn@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:2393:2559:2562:3138:3139:3140:3141:3142:3152:3353:3865:3867:3868:3870:3874:4250:4321:5007:6120:6261:6653:7901:9969:10004:10400:11026:11232:11473:11657:11658:11914:12043:12114:12296:12297:12438:12555:12895:12986:13069:13255:13311:13357:13846:14181:14394:14659:14721:21080:21365:21444:21451:21627:30054:30064:30070,0,RBL:209.85.222.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:26,LUA_SUMMARY:none X-HE-Tag: bulb25_79966a74cdf17 X-Filterd-Recvd-Size: 4304 Received: from mail-ua1-f73.google.com (mail-ua1-f73.google.com [209.85.222.73]) by imf11.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:55 +0000 (UTC) Received: by mail-ua1-f73.google.com with SMTP id i7so694581uak.7 for ; Fri, 18 Oct 2019 02:43:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=n3tegVRp4MiUZ3IxpD/O7xdpLdlNBdCMHTjiqcPBuqc=; b=Ic4WoERO5kGMVe/BlgNsGosgqqkC3W8qXq0Og5oZ3pMOaVXBowh3AAkb6vhdVmIuR9 FDWKuV03TO8SdvFELIcvm4YNsdQgvqO8UcaWh+uahcVWX/bwkmwyccGerruYEiomF7Iw 0diCrwl1Qd/MBUc/T/luYHsMnsz4wpndjQgZX1wWQKoOPnaJgbbNnHyWwwQTEgOlD+Jx x8jAbVcaJLj97y+364Gly124W0HwNiGA79RrssgY9pq8rEsLnQpZ+Xn027aqekFGwxjQ R3UuDV2KlPdWuDr0rPjfs5TTspgz+gZA+zLSSEst/J2L0/ur0y2vNgCwc4wW/XSw/Ena oesg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=n3tegVRp4MiUZ3IxpD/O7xdpLdlNBdCMHTjiqcPBuqc=; b=aCDabWdZML1bRm+7eFmbf481IxGorjiY/Lmt+AmUa8aLlJcZkaBbtwuEGQlBwcMWWt DcU1mY3lh7CMAMx33tcEjuiX3b27/WVQX6X2AnOBve6qllA2BnyjmfbGc9zQNAcHOGLV h/M0wTJ9yYCxAVohftk3jhUPZpAbZbJW9n5eomdBxf+ZkOlOrlHr8RaA2xODPXRX6+ab tmguYHZyL29Im2kmso02thz3yHnF0FTnLcgvC1/5A0G4JVlxwYt02vK+W2kzPqvYtbpR pPW0sMQJBoHBGWW5xGSPSEVEC8t3bu15OxsX05emj24SqhLKsJVXAn8qmKRNNti6J2mR HLEA== X-Gm-Message-State: APjAAAWH+HxmnAiY/iBmDP5BAmXgi3Zi8bDXU6zAJrbvoE3unyHvFkQV exq++XtFwbgUvQCjv1A/AzfSKmK9USM= X-Google-Smtp-Source: APXvYqw181HlPSre4wn2wQWTT7FG+8QFUj2gKPyK+zT5YySCW4Wg5lPxRT3H2cAVsnsVU7Ay6uHMBCx+g9Q= X-Received: by 2002:a67:8841:: with SMTP id k62mr5006513vsd.101.1571391834605; Fri, 18 Oct 2019 02:43:54 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:52 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-15-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 14/26] kmsan: make READ_ONCE_TASK_STACK() return initialized values From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: To avoid false positives, assume that reading from the task stack always produces initialized values. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: Ie73e5a41fdc8195699928e65f5cbe0d3d3c9e2fa --- arch/x86/include/asm/unwind.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index 499578f7e6d7..f60c2bd1ddf2 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h @@ -100,9 +100,10 @@ void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, #endif /* - * This disables KASAN checking when reading a value from another task's stack, - * since the other task could be running on another CPU and could have poisoned - * the stack in the meantime. + * This disables KASAN/KMSAN checking when reading a value from another task's + * stack, since the other task could be running on another CPU and could have + * poisoned the stack in the meantime. Frame pointers are uninitialized by + * default, so for KMSAN we mark the return value initialized unconditionally. */ #define READ_ONCE_TASK_STACK(task, x) \ ({ \ @@ -111,7 +112,7 @@ void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, val = READ_ONCE(x); \ else \ val = READ_ONCE_NOCHECK(x); \ - val; \ + KMSAN_INIT_VALUE(val); \ }) static inline bool task_on_another_cpu(struct task_struct *task) From patchwork Fri Oct 18 09:42:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197995 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3630418A6 for ; Fri, 18 Oct 2019 09:44:03 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id DCC8B222C5 for ; Fri, 18 Oct 2019 09:44:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="aWDVsodl" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DCC8B222C5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id EE5338E002A; Fri, 18 Oct 2019 05:43:59 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id EBFAB8E0003; Fri, 18 Oct 2019 05:43:59 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D85F28E002A; Fri, 18 Oct 2019 05:43:59 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0220.hostedemail.com [216.40.44.220]) by kanga.kvack.org (Postfix) with ESMTP id AA83E8E0003 for ; Fri, 18 Oct 2019 05:43:59 -0400 (EDT) Received: from smtpin13.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with SMTP id 5234BEFB1 for ; Fri, 18 Oct 2019 09:43:59 +0000 (UTC) X-FDA: 76056418998.13.bat80_7a0d31c771a0e X-Spam-Summary: 2,0,0,0d33b859f55e6920,d41d8cd98f00b204,3xympxqykcaoqvsno1qyyqvo.mywvsx47-wwu5kmu.y1q@flex--glider.bounces.google.com,:glider@google.com:herbert@gondor.apana.org.au:harry.wentland@amd.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:1:41:152:355:379:541:800:960:967:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1593:1594:1605:1730:1747:1777:1792:1801:2393:2525:2559:2564:2636:2682:2685:2693:2859:2933:2937:2939:2942:2945:2947:2951:2954:3022:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:3873:3934:3936:3938:3941:3944:3947:3950:3953:3956:3959:4250:4321:4605:5007:6120:6261:6609:6653:7875:7901:7903:8957:9025:9969:10004:11026:11232:11473:11657:11658:11914:12043:12291:12296:12297:12438:12555:12895:12986:13141:13161:13229:13230:13255:13846:14096:14097:14394:14659:21063:21080:21325:21365:21444:21451:21627:30003:30054:30055:30062:30064,0,RBL:error,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNS BL:neutr X-HE-Tag: bat80_7a0d31c771a0e X-Filterd-Recvd-Size: 12938 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf03.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:43:58 +0000 (UTC) Received: by mail-wr1-f73.google.com with SMTP id 7so2369447wrl.2 for ; Fri, 18 Oct 2019 02:43:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=16iSBNChTS//BwkKZiXK7QkCvle7X7xoItbrk/YSKlw=; b=aWDVsodlEc8wd0V5eWM4Im7yWXkzQ1UnnMbvBGVw9KzHsmpfPzr11qyzSsc0hcoGSr mTPZFmbXICkYyssiW0VnXx0UuzlLXL/8BAzZOdOySXjWRVyZ2p2c3ab1zrjQChtaEyGn jJzNBX3hadbyajEe/OkYdh/mYYgciGcji2AgN7AiMKZ9b8eJ01vXKhyPIPIhuusVSns9 Bgtr1vpesa5b0QszRB5euX03mAZYEfZwsutIcWQ0DY1Yd/t+EFQDUICAS88IjUJPynCb rZC+x4qSpF7ktaVJXCMpx1HpqGre/nXP5dU6MFN6ncUIYLh+Uk7Sy75xXyW57zIyda2+ McSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=16iSBNChTS//BwkKZiXK7QkCvle7X7xoItbrk/YSKlw=; b=o6wMv7gnQpBK/tt5LeNulKxHvFEzlZpBHmLVqN0uBuwfUfyw95cVJVvxTgdaBR3In/ UBttSHobAG38ekFYZCphQb74vILxF7JxsiXpUod0lXcpqZB/xiIHCihxzl5qLiQteN2b TUzNOuYehxp8mxo2lE9CgzjLhkn1rJKKtr21yY2Dc7eHej+a+3/gGcJoZD/uEcG6Uba9 cVlWRjZjiSGkQcXnLR5Eq/luh/hS5zhv6x8a9fNSQdqhCdWkkkJUsOe5dIhHiwzvVbtl xao53NJ04o4MMduqBcd/rcnIICRB0c/4rsOx2bR4p0w/+yCmOT6/mQ0I19RJAK/HQq8R GnEA== X-Gm-Message-State: APjAAAVaehlXtnhtbQtWf7RXGqjasSz+9cKy24Eb3KbJ+EfSKdgn1K4E D+3C1ItHt9E81dU4mymXYbELpTdfhEg= X-Google-Smtp-Source: APXvYqwT0iZb6l0M2+johcjxTo0JAB6JKQjy96s8fyMtBFI9cGGk32b7lSceiI+K/eg6TDC0W8kzC4VCAZk= X-Received: by 2002:adf:de85:: with SMTP id w5mr6766740wrl.278.1571391837470; Fri, 18 Oct 2019 02:43:57 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:53 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-16-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 15/26] kmsan: Kconfig changes to disable options incompatible with KMSAN From: glider@google.com To: Alexander Potapenko Cc: Herbert Xu , Harry Wentland , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Certain config options are currently incompatible with KMSAN, disable them. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Herbert Xu Cc: Harry Wentland Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org Acked-by: Harry Wentland --- Change-Id: I4521f5c764cfaeba2fae79c954925c302c5e3bc0 --- arch/Kconfig | 2 +- arch/x86/Kconfig | 1 + arch/x86/Kconfig.debug | 3 +++ crypto/Kconfig | 26 ++++++++++++++++++++++++++ drivers/gpu/drm/amd/display/Kconfig | 2 +- lib/Kconfig.debug | 3 +++ 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 5f8a5d84dbbe..d5ca838ae8ad 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -843,7 +843,7 @@ config HAVE_ARCH_VMAP_STACK config VMAP_STACK default y bool "Use a virtually-mapped stack" - depends on HAVE_ARCH_VMAP_STACK && !KASAN + depends on HAVE_ARCH_VMAP_STACK && !KASAN && !KMSAN ---help--- Enable this if you want the use virtually-mapped kernel stacks with guard pages. This causes kernel stack overflows to be diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 3f83a5c53808..6d2b0fb3a871 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2143,6 +2143,7 @@ config RELOCATABLE config RANDOMIZE_BASE bool "Randomize the address of the kernel image (KASLR)" depends on RELOCATABLE + depends on !KMSAN default y ---help--- In support of Kernel Address Space Layout Randomization (KASLR), diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index bf9cd83de777..db3cd6147829 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -292,6 +292,9 @@ choice config UNWINDER_ORC bool "ORC unwinder" depends on X86_64 + # KMSAN doesn't support UNWINDER_ORC yet, + # see https://github.com/google/kmsan/issues/48. + depends on !KMSAN select STACK_VALIDATION ---help--- This option enables the ORC (Oops Rewind Capability) unwinder for diff --git a/crypto/Kconfig b/crypto/Kconfig index 9e524044d312..37a22711012c 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -309,11 +309,13 @@ config CRYPTO_AEGIS128 config CRYPTO_AEGIS128_SIMD bool "Support SIMD acceleration for AEGIS-128" depends on CRYPTO_AEGIS128 && ((ARM || ARM64) && KERNEL_MODE_NEON) + depends on !KMSAN default y config CRYPTO_AEGIS128_AESNI_SSE2 tristate "AEGIS-128 AEAD algorithm (x86_64 AESNI+SSE2 implementation)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_AEAD select CRYPTO_SIMD help @@ -571,6 +573,7 @@ config CRYPTO_CRC32C config CRYPTO_CRC32C_INTEL tristate "CRC32c INTEL hardware acceleration" depends on X86 + depends on !KMSAN select CRYPTO_HASH help In Intel processor with SSE4.2 supported, the processor will @@ -611,6 +614,7 @@ config CRYPTO_CRC32 config CRYPTO_CRC32_PCLMUL tristate "CRC32 PCLMULQDQ hardware acceleration" depends on X86 + depends on !KMSAN select CRYPTO_HASH select CRC32 help @@ -649,6 +653,7 @@ config CRYPTO_CRCT10DIF config CRYPTO_CRCT10DIF_PCLMUL tristate "CRCT10DIF PCLMULQDQ hardware acceleration" depends on X86 && 64BIT && CRC_T10DIF + depends on !KMSAN select CRYPTO_HASH help For x86_64 processors with SSE4.2 and PCLMULQDQ supported, @@ -695,6 +700,7 @@ config CRYPTO_POLY1305 config CRYPTO_POLY1305_X86_64 tristate "Poly1305 authenticator algorithm (x86_64/SSE2/AVX2)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_POLY1305 help Poly1305 authenticator algorithm, RFC7539. @@ -814,6 +820,7 @@ config CRYPTO_SHA1 config CRYPTO_SHA1_SSSE3 tristate "SHA1 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_SHA1 select CRYPTO_HASH help @@ -825,6 +832,7 @@ config CRYPTO_SHA1_SSSE3 config CRYPTO_SHA256_SSSE3 tristate "SHA256 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_SHA256 select CRYPTO_HASH help @@ -837,6 +845,7 @@ config CRYPTO_SHA256_SSSE3 config CRYPTO_SHA512_SSSE3 tristate "SHA512 digest algorithm (SSSE3/AVX/AVX2)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_SHA512 select CRYPTO_HASH help @@ -1011,6 +1020,7 @@ config CRYPTO_WP512 config CRYPTO_GHASH_CLMUL_NI_INTEL tristate "GHASH hash function (CLMUL-NI accelerated)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_CRYPTD help This is the x86_64 CLMUL-NI accelerated implementation of @@ -1064,6 +1074,7 @@ config CRYPTO_AES_TI config CRYPTO_AES_NI_INTEL tristate "AES cipher algorithms (AES-NI)" depends on X86 + depends on !KMSAN select CRYPTO_AEAD select CRYPTO_LIB_AES select CRYPTO_ALGAPI @@ -1190,6 +1201,7 @@ config CRYPTO_BLOWFISH_COMMON config CRYPTO_BLOWFISH_X86_64 tristate "Blowfish cipher algorithm (x86_64)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_BLOWFISH_COMMON help @@ -1221,6 +1233,7 @@ config CRYPTO_CAMELLIA_X86_64 tristate "Camellia cipher algorithm (x86_64)" depends on X86 && 64BIT depends on CRYPTO + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_GLUE_HELPER_X86 help @@ -1238,6 +1251,7 @@ config CRYPTO_CAMELLIA_AESNI_AVX_X86_64 tristate "Camellia cipher algorithm (x86_64/AES-NI/AVX)" depends on X86 && 64BIT depends on CRYPTO + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_CAMELLIA_X86_64 select CRYPTO_GLUE_HELPER_X86 @@ -1258,6 +1272,7 @@ config CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 tristate "Camellia cipher algorithm (x86_64/AES-NI/AVX2)" depends on X86 && 64BIT depends on CRYPTO + depends on !KMSAN select CRYPTO_CAMELLIA_AESNI_AVX_X86_64 help Camellia cipher algorithm module (x86_64/AES-NI/AVX2). @@ -1303,6 +1318,7 @@ config CRYPTO_CAST5 config CRYPTO_CAST5_AVX_X86_64 tristate "CAST5 (CAST-128) cipher algorithm (x86_64/AVX)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_CAST5 select CRYPTO_CAST_COMMON @@ -1325,6 +1341,7 @@ config CRYPTO_CAST6 config CRYPTO_CAST6_AVX_X86_64 tristate "CAST6 (CAST-256) cipher algorithm (x86_64/AVX)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_CAST6 select CRYPTO_CAST_COMMON @@ -1360,6 +1377,7 @@ config CRYPTO_DES_SPARC64 config CRYPTO_DES3_EDE_X86_64 tristate "Triple DES EDE cipher algorithm (x86-64)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_LIB_DES help @@ -1426,6 +1444,7 @@ config CRYPTO_CHACHA20 config CRYPTO_CHACHA20_X86_64 tristate "ChaCha stream cipher algorithms (x86_64/SSSE3/AVX2/AVX-512VL)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_CHACHA20 help @@ -1462,6 +1481,7 @@ config CRYPTO_SERPENT config CRYPTO_SERPENT_SSE2_X86_64 tristate "Serpent cipher algorithm (x86_64/SSE2)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT @@ -1481,6 +1501,7 @@ config CRYPTO_SERPENT_SSE2_X86_64 config CRYPTO_SERPENT_SSE2_586 tristate "Serpent cipher algorithm (i586/SSE2)" depends on X86 && !64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT @@ -1500,6 +1521,7 @@ config CRYPTO_SERPENT_SSE2_586 config CRYPTO_SERPENT_AVX_X86_64 tristate "Serpent cipher algorithm (x86_64/AVX)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SERPENT @@ -1520,6 +1542,7 @@ config CRYPTO_SERPENT_AVX_X86_64 config CRYPTO_SERPENT_AVX2_X86_64 tristate "Serpent cipher algorithm (x86_64/AVX2)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_SERPENT_AVX_X86_64 help Serpent cipher algorithm, by Anderson, Biham & Knudsen. @@ -1615,6 +1638,7 @@ config CRYPTO_TWOFISH_586 config CRYPTO_TWOFISH_X86_64 tristate "Twofish cipher algorithm (x86_64)" depends on (X86 || UML_X86) && 64BIT + depends on !KMSAN select CRYPTO_ALGAPI select CRYPTO_TWOFISH_COMMON help @@ -1631,6 +1655,7 @@ config CRYPTO_TWOFISH_X86_64 config CRYPTO_TWOFISH_X86_64_3WAY tristate "Twofish cipher algorithm (x86_64, 3-way parallel)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_TWOFISH_COMMON select CRYPTO_TWOFISH_X86_64 @@ -1652,6 +1677,7 @@ config CRYPTO_TWOFISH_X86_64_3WAY config CRYPTO_TWOFISH_AVX_X86_64 tristate "Twofish cipher algorithm (x86_64/AVX)" depends on X86 && 64BIT + depends on !KMSAN select CRYPTO_BLKCIPHER select CRYPTO_GLUE_HELPER_X86 select CRYPTO_SIMD diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig index 71991a28a775..99585eaf4dd0 100644 --- a/drivers/gpu/drm/amd/display/Kconfig +++ b/drivers/gpu/drm/amd/display/Kconfig @@ -6,7 +6,7 @@ config DRM_AMD_DC bool "AMD DC - Enable new display engine" default y select SND_HDA_COMPONENT if SND_HDA_CORE - select DRM_AMD_DC_DCN1_0 if X86 && !(KCOV_INSTRUMENT_ALL && KCOV_ENABLE_COMPARISONS) + select DRM_AMD_DC_DCN1_0 if X86 && !(KCOV_INSTRUMENT_ALL && KCOV_ENABLE_COMPARISONS) && !KMSAN help Choose this option if you want to use the new display engine support for AMDGPU. This adds required support for Vega and diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 75c36318943d..a3f6f5d68593 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1068,6 +1068,9 @@ menu "Lock Debugging (spinlocks, mutexes, etc...)" config LOCK_DEBUGGING_SUPPORT bool depends on TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT + # KMSAN is incompatible with lockdep, + # see https://github.com/google/kmsan/issues/57. + depends on !KMSAN default y config PROVE_LOCKING From patchwork Fri Oct 18 09:42:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197997 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EF04913B1 for ; Fri, 18 Oct 2019 09:44:05 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id AE99420820 for ; Fri, 18 Oct 2019 09:44:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dHJwyo4n" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AE99420820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 794DB8E002B; Fri, 18 Oct 2019 05:44:02 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 71DB38E0003; Fri, 18 Oct 2019 05:44:02 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 60A398E002B; Fri, 18 Oct 2019 05:44:02 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 3596D8E0003 for ; Fri, 18 Oct 2019 05:44:02 -0400 (EDT) Received: from smtpin20.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with SMTP id D80C1A2D0 for ; Fri, 18 Oct 2019 09:44:01 +0000 (UTC) X-FDA: 76056419082.20.hand70_7a6ed3fafca0c X-Spam-Summary: 10,1,0,175d4173fd21541a,d41d8cd98f00b204,3yimpxqykca0tyvqr4t11tyr.p1zyv07a-zzx8npx.14t@flex--glider.bounces.google.com,:glider@google.com:axboe@kernel.dk:luto@kernel.org:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:1:41:152:334:355:379:541:617:800:960:973:982:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1593:1594:1605:1690:1730:1747:1777:1792:1801:2197:2198:2199:2200:2393:2553:2559:2562:2637:2897:2904:3138:3139:3140:3141:3142:3152:3653:3865:3866:3867:3868:3870:3871:4250:4321:4605:5007:6119:6120:6261:6653:7875:7901:7903:7974:8603:8660:8784:9969:10004:11026:11232:11473:11657:11658:11914:12043:12296:12297:12438:12555:12895:12986:13146:13148:13230:13846:14394:14659:14877:21080:21220:21221:21365:21433:21444:21451:21611:21627:21740:21795:21966:30003:30051:30054:30064:30069:30070:30080:30090,0,RBL:209.85.222.202:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,Domain Cache:0, X-HE-Tag: hand70_7a6ed3fafca0c X-Filterd-Recvd-Size: 13791 Received: from mail-qk1-f202.google.com (mail-qk1-f202.google.com [209.85.222.202]) by imf05.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:01 +0000 (UTC) Received: by mail-qk1-f202.google.com with SMTP id c4so390210qkg.22 for ; Fri, 18 Oct 2019 02:44:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=wzjhPFLgc4dnmBIO1rbgzyvtsjkcRh993a9RjYmhJo0=; b=dHJwyo4nrVc46fqMRsanExMWZtTOE9bZ6QQn990dE2mogazVXL84AUfIDE4z71ueLt vKDO2tMjXPhZF6Ehn1kQzfgBap/9+fqmK7QvHsrVVA37Ud4zxCwOh8RmJ6ER7FpUJJCy 30ZFUMXaf5Qaat6aX2uiEW/zw/ciJJI4k1EOZ3vRgLaU/9jeUzLsEp6N6g0/0hAw8hrY VjORpF//e4faHlQvdm8xkzWH8M2IUwmCBdodugjhfv4PnIj3RNxKzgoeGPORKYatQ5yz 19E8PBQH8eohAH0BXH9iJAAxr35hWO+klbNQ0s6vGHve/IdH6aj07tD8Ez2eZkqPHMoe Yszg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=wzjhPFLgc4dnmBIO1rbgzyvtsjkcRh993a9RjYmhJo0=; b=iNEUawvkN6cTKwKGmoX/uiLqdKC7RRyfQjZfSlDTe/j6z1NKEhn6p5vAcFt9UKbaju wT/acfoV19FDPCc9gngm5EeAdr6WAf9vIx2XRmFX3I434BmRsRseaVxaqBNdn79N4Vq1 Fm0R/dsBPgdno51DPwgSxK6Y5fN4YkIYq/+STOs7ra+ZdXMDVM1MPi9m+aT4SHELtdAE Fm646nl1F4pwzCtRjMJARK/nPPp9U2UuxK4vi+sdZ79T1+ytsPUczfgF7aO6ocZqtbLW nJD4MT41UZQ/WJduoMyMK8HRXZRuyMUi6Jsw/YyxEBDPxTpF+SVtXUocRj0rSrWlQez6 QuJg== X-Gm-Message-State: APjAAAXZJK3CbBmypv3uwrhrVK/B0MH7D9E3s7m7dpIL+IMOi1LTWB4c VQKjL4UDvyBhYL6CtLwuC8qY0hAaPMA= X-Google-Smtp-Source: APXvYqwxZZ1jrItTC477pbeNJSNjQfHcElRa4bN9IKVhHx0k6ZwSMEioykWGZc8/zd05MEQnu/hAX2dbn5Y= X-Received: by 2002:a0c:f792:: with SMTP id s18mr8669465qvn.20.1571391840593; Fri, 18 Oct 2019 02:44:00 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:54 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-17-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 16/26] kmsan: Changing existing files to enable KMSAN builds From: glider@google.com To: Alexander Potapenko Cc: Jens Axboe , Andy Lutomirski , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Do the following to make KMSAN usable: - add KMSAN declarations to struct page and struct task_struct; - add Makefile.kmsan to top-level Makefile; - call KMSAN initialization from init/main.c - add asm hooks to arch/x86/entry/entry_64.S; - increase task stack size under KMSAN; - disable page merging in block/blk.h; - disable CONFIG_KMSAN in arch/x86/boot/compressed/misc.h to use default string functions instead of KMSAN ones. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Jens Axboe Cc: Andy Lutomirski Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I37e0b7f2d2f2b0aeac5753ff9d6b411485fc374e --- Makefile | 3 ++- arch/x86/boot/compressed/misc.h | 1 + arch/x86/entry/entry_64.S | 18 ++++++++++++++++++ arch/x86/include/asm/page_64_types.h | 12 +++++++----- block/blk.h | 7 +++++++ include/linux/mm_types.h | 9 +++++++++ include/linux/sched.h | 5 +++++ init/main.c | 3 +++ lib/stackdepot.c | 7 ++++--- mm/Makefile | 1 + scripts/Makefile.lib | 6 ++++++ 11 files changed, 63 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index ffd7a912fc46..5041e908f051 100644 --- a/Makefile +++ b/Makefile @@ -478,7 +478,7 @@ export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE -export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN +export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN CFLAGS_KMSAN export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL @@ -898,6 +898,7 @@ KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) endif include scripts/Makefile.kasan +include scripts/Makefile.kmsan include scripts/Makefile.extrawarn include scripts/Makefile.ubsan diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index c8181392f70d..dd4bd8c5d97a 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -12,6 +12,7 @@ #undef CONFIG_PARAVIRT_XXL #undef CONFIG_PARAVIRT_SPINLOCKS #undef CONFIG_KASAN +#undef CONFIG_KMSAN /* cpu_feature_enabled() cannot be used this early */ #define USE_EARLY_PGTABLE_L5 diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index b7c3ea4cb19d..1218672bad85 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -168,12 +169,14 @@ GLOBAL(entry_SYSCALL_64_after_hwframe) PUSH_AND_CLEAR_REGS rax=$-ENOSYS TRACE_IRQS_OFF + KMSAN_SYSCALL_ENTER /* IRQs are off. */ movq %rax, %rdi movq %rsp, %rsi call do_syscall_64 /* returns with IRQs disabled */ + KMSAN_SYSCALL_EXIT TRACE_IRQS_IRETQ /* we're about to change IF */ /* @@ -575,6 +578,7 @@ ENTRY(interrupt_entry) 1: ENTER_IRQ_STACK old_rsp=%rdi save_ret=1 + KMSAN_INTERRUPT_ENTER /* We entered an interrupt context - irqs are off: */ TRACE_IRQS_OFF @@ -604,12 +608,14 @@ common_interrupt: addq $-0x80, (%rsp) /* Adjust vector to [-256, -1] range */ call interrupt_entry UNWIND_HINT_REGS indirect=1 + KMSAN_UNPOISON_PT_REGS call do_IRQ /* rdi points to pt_regs */ /* 0(%rsp): old RSP */ ret_from_intr: DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF + KMSAN_INTERRUPT_EXIT LEAVE_IRQ_STACK testb $3, CS(%rsp) @@ -802,6 +808,7 @@ ENTRY(\sym) .Lcommon_\sym: call interrupt_entry UNWIND_HINT_REGS indirect=1 + KMSAN_UNPOISON_PT_REGS call \do_sym /* rdi points to pt_regs */ jmp ret_from_intr END(\sym) @@ -909,15 +916,18 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt .if \shift_ist != -1 subq $\ist_offset, CPU_TSS_IST(\shift_ist) + KMSAN_IST_ENTER(\shift_ist) .endif .if \read_cr2 movq %r12, %rdx /* Move CR2 into 3rd argument */ .endif + KMSAN_UNPOISON_PT_REGS call \do_sym .if \shift_ist != -1 + KMSAN_IST_EXIT(\shift_ist) addq $\ist_offset, CPU_TSS_IST(\shift_ist) .endif @@ -1079,7 +1089,9 @@ ENTRY(do_softirq_own_stack) pushq %rbp mov %rsp, %rbp ENTER_IRQ_STACK regs=0 old_rsp=%r11 + KMSAN_SOFTIRQ_ENTER call __do_softirq + KMSAN_SOFTIRQ_EXIT LEAVE_IRQ_STACK regs=0 leaveq ret @@ -1466,9 +1478,12 @@ ENTRY(nmi) * done with the NMI stack. */ + KMSAN_NMI_ENTER movq %rsp, %rdi movq $-1, %rsi + KMSAN_UNPOISON_PT_REGS call do_nmi + KMSAN_NMI_EXIT /* * Return back to user mode. We must *not* do the normal exit @@ -1678,10 +1693,13 @@ end_repeat_nmi: call paranoid_entry UNWIND_HINT_REGS + KMSAN_NMI_ENTER /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp, %rdi movq $-1, %rsi + KMSAN_UNPOISON_PT_REGS call do_nmi + KMSAN_NMI_EXIT /* Always restore stashed CR3 value (see paranoid_entry) */ RESTORE_CR3 scratch_reg=%r15 save_reg=%r14 diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index 288b065955b7..ea9fbf09f43b 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h @@ -7,18 +7,20 @@ #endif #ifdef CONFIG_KASAN -#define KASAN_STACK_ORDER 1 +#define EXTRA_STACK_ORDER 1 +#elif defined(CONFIG_KMSAN) +#define EXTRA_STACK_ORDER 2 #else -#define KASAN_STACK_ORDER 0 +#define EXTRA_STACK_ORDER 0 #endif -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) +#define THREAD_SIZE_ORDER (2 + EXTRA_STACK_ORDER) #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) -#define EXCEPTION_STACK_ORDER (0 + KASAN_STACK_ORDER) +#define EXCEPTION_STACK_ORDER (0 + EXTRA_STACK_ORDER) #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) -#define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER) +#define IRQ_STACK_ORDER (2 + EXTRA_STACK_ORDER) #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) /* diff --git a/block/blk.h b/block/blk.h index 47fba9362e60..9ee271a22423 100644 --- a/block/blk.h +++ b/block/blk.h @@ -78,6 +78,13 @@ static inline bool biovec_phys_mergeable(struct request_queue *q, phys_addr_t addr1 = page_to_phys(vec1->bv_page) + vec1->bv_offset; phys_addr_t addr2 = page_to_phys(vec2->bv_page) + vec2->bv_offset; +#ifdef CONFIG_KMSAN + /* + * Merging consequent physical pages may not work correctly under KMSAN + * if their metadata pages aren't consequent. Just disable merging. + */ + return false; +#endif if (addr1 + vec1->bv_len != addr2) return false; if (xen_domain() && !xen_biovec_phys_mergeable(vec1, vec2->bv_page)) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 2222fa795284..c87c5416a802 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -216,6 +216,15 @@ struct page { not kmapped, ie. highmem) */ #endif /* WANT_PAGE_VIRTUAL */ +#ifdef CONFIG_KMSAN + /* + * Bits in struct page are scarce, so the LSB in *shadow is used to + * indicate whether the page should be ignored by KMSAN or not. + */ + struct page *shadow; + struct page *origin; +#endif + #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS int _last_cpupid; #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 7417e0207b48..e0f6e95c22ed 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1172,6 +1173,10 @@ struct task_struct { unsigned int kasan_depth; #endif +#ifdef CONFIG_KMSAN + struct kmsan_task_state kmsan; +#endif + #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* Index of current stored address in ret_stack: */ int curr_ret_stack; diff --git a/init/main.c b/init/main.c index 91f6ebb30ef0..afcca2a38348 100644 --- a/init/main.c +++ b/init/main.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -554,6 +555,7 @@ static void __init mm_init(void) */ page_ext_init_flatmem(); report_meminit(); + kmsan_initialize_shadow(); mem_init(); kmem_cache_init(); kmemleak_init(); @@ -625,6 +627,7 @@ asmlinkage __visible void __init start_kernel(void) sort_main_extable(); trap_init(); mm_init(); + kmsan_initialize(); ftrace_init(); diff --git a/lib/stackdepot.c b/lib/stackdepot.c index 460efd3ef742..529a86eb1dd1 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -233,8 +233,8 @@ unsigned int stack_depot_fetch(depot_stack_handle_t handle, if (parts.slabindex > depot_index) { WARN(1, "slab index %d out of bounds (%d) for stack id %08x\n", parts.slabindex, depot_index, handle); - __memset(trace, 0, sizeof(*trace)); - return; + *entries = NULL; + return 0; } slab = stack_slabs[parts.slabindex]; stack = slab + offset; @@ -299,7 +299,8 @@ depot_stack_handle_t stack_depot_save(unsigned long *entries, * contexts and I/O. */ alloc_flags &= ~GFP_ZONEMASK; - alloc_flags &= (GFP_ATOMIC | GFP_KERNEL); + alloc_flags &= (GFP_ATOMIC | GFP_KERNEL | + __GFP_NO_KMSAN_SHADOW); alloc_flags |= __GFP_NOWARN; page = alloc_pages(alloc_flags, STACK_ALLOC_ORDER); if (page) diff --git a/mm/Makefile b/mm/Makefile index d996846697ef..419e6e02dfaf 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -71,6 +71,7 @@ obj-$(CONFIG_PAGE_POISONING) += page_poison.o obj-$(CONFIG_SLAB) += slab.o obj-$(CONFIG_SLUB) += slub.o obj-$(CONFIG_KASAN) += kasan/ +obj-$(CONFIG_KMSAN) += kmsan/ obj-$(CONFIG_FAILSLAB) += failslab.o obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o obj-$(CONFIG_MEMTEST) += memtest.o diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 179d55af5852..f9f38f7c1cd4 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -140,6 +140,12 @@ _c_flags += $(if $(patsubst n%,, \ $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE)) endif +ifeq ($(CONFIG_KMSAN),y) +_c_flags += $(if $(patsubst n%,, \ + $(KMSAN_SANITIZE_$(basetarget).o)$(KMSAN_SANITIZE)y), \ + $(CFLAGS_KMSAN)) +endif + ifeq ($(CONFIG_UBSAN),y) _c_flags += $(if $(patsubst n%,, \ $(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \ From patchwork Fri Oct 18 09:42:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11197999 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6A77613B1 for ; Fri, 18 Oct 2019 09:44:08 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 2D47B20820 for ; Fri, 18 Oct 2019 09:44:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="vsyAjKGh" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2D47B20820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id AEDD78E002C; Fri, 18 Oct 2019 05:44:05 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id A9E6C8E0003; Fri, 18 Oct 2019 05:44:05 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9669F8E002C; Fri, 18 Oct 2019 05:44:05 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0219.hostedemail.com [216.40.44.219]) by kanga.kvack.org (Postfix) with ESMTP id 7009D8E0003 for ; Fri, 18 Oct 2019 05:44:05 -0400 (EDT) Received: from smtpin29.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with SMTP id 13DDD82FCD3A for ; Fri, 18 Oct 2019 09:44:05 +0000 (UTC) X-FDA: 76056419250.29.bun44_7ae6f7c74513d X-Spam-Summary: 2,0,0,86f46d290248efba,d41d8cd98f00b204,3y4mpxqykcbaw1ytu7w44w1u.s421y3ad-220bqs0.47w@flex--glider.bounces.google.com,:glider@google.com:ard.biesheuvel@linaro.org:tglx@linutronix.de:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:2:41:152:355:379:541:800:960:968:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1535:1593:1594:1605:1730:1747:1777:1792:1801:2393:2559:2562:2693:2902:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:4049:4119:4250:4321:4605:5007:6120:6261:6609:6653:7875:7901:7903:8603:8660:9969:10004:11026:11232:11473:11657:11658:11914:12043:12296:12297:12438:12555:12895:12986:13148:13230:13255:13846:14394:14659:21080:21365:21444:21451:21627:21740:21939:30012:30054:30064,0,RBL:209.85.128.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:2,LUA_SUMMARY:none X-HE-Tag: bun44_7ae6f7c74513d X-Filterd-Recvd-Size: 8693 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf04.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:04 +0000 (UTC) Received: by mail-wm1-f73.google.com with SMTP id s19so2091221wmj.0 for ; Fri, 18 Oct 2019 02:44:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=dNath48vQTBMVQXnzCATu0xdx30hemcbKRrG/s8XfbY=; b=vsyAjKGhlqrolkyaBSOfd1ZlIhUif9mZcQs5aIHkZqxL9G1Fmpj25vs/x9s29Qylhj cwodkIJvU4Yg8V77Yd8ZdP7ah2UXgfECWZ7htO+RPrhEq3cot3krji7EmCaJrubxFc3b yYYCWKF/A+C7RWZ8v8+gXIvzpUu41bJc8yYf2CHE7psTuivyRaO6kEaq9R77OC3kNHoH /Y9AMTv1b4a4S34uanAWIDdDJAOEXySoHhuavmss/x4CkHcG6BL2DJvjxvlSlfwVC+ul uaHSQNzx60lWI1tkD5x6e8RO+dvcQzhNzIK2IjK6R79AJijfqjH0ebgA0PLIMnudfg7I dk/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=dNath48vQTBMVQXnzCATu0xdx30hemcbKRrG/s8XfbY=; b=AIFviolG20W8Jly/vL7pSSJNoMutMVaSBfntQLeOwx3hYS8ZHXKYCBOjMU4mZ1D92Y u2CQo0DxHp+hOAwEr0tPBYGoSOSc5jgjIddFUw2TuiT65yOrayQ2c8/yYSve//Fh4uaq f/FLJSymtn2K31d97mp3SEYzF1yUA6qq9mR8JPAUHKYX7bbfjCz/qiQDLzy2A7vwCdh4 rGdUTpEfLFj8AkNRn5T3HlzFDNcYS2UVzyptKNVEaVGYw9hbvqaPZrYnag4030UJ5BOP qwnEx0HtswgXuZ0uPzqvGUXgMGxqaJ8iP3G+RQWHxgDbealxZDDdDy4MyEKLgsFgH+08 voGg== X-Gm-Message-State: APjAAAVlmt4cW5y24P28/PMRYSlNMVeuEQEfOxzQCeG4950WNEeWAI39 6sk0SfDNziPU5TUfqkngb5IEREIRvoI= X-Google-Smtp-Source: APXvYqw5bMbuPpXCqJViRjo98scmuA2/XXOgWAXLhgm/dgJ19/uzwm5If7diQs0wnwjR1ch21gIEKv4gzfA= X-Received: by 2002:adf:ed4a:: with SMTP id u10mr7361941wro.256.1571391843250; Fri, 18 Oct 2019 02:44:03 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:55 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-18-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 17/26] kmsan: disable KMSAN instrumentation for certain kernel parts From: glider@google.com To: Alexander Potapenko Cc: Ard Biesheuvel , Thomas Gleixner , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Instrumenting some files with KMSAN will result in kernel being unable to link, boot or crashing at runtime for various reasons (e.g. infinite recursion caused by instrumentation hooks calling instrumented code again). Disable KMSAN in the following places: - arch/x86/boot and arch/x86/realmode/rm, as KMSAN doesn't work for i386; - arch/x86/entry/vdso, which isn't linked with KMSAN runtime; - three files in arch/x86/kernel - boot problems; - arch/x86/mm/cpu_entry_area.c - recursion; - EFI stub - build failures; - kcov, stackdepot - recursion. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Ard Biesheuvel Cc: Thomas Gleixner Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I90961eabf2dcb9ae992aed259088953bad5e4d6d --- arch/x86/boot/Makefile | 2 ++ arch/x86/boot/compressed/Makefile | 2 ++ arch/x86/entry/vdso/Makefile | 3 +++ arch/x86/kernel/Makefile | 4 ++++ arch/x86/kernel/cpu/Makefile | 1 + arch/x86/mm/Makefile | 2 ++ arch/x86/realmode/rm/Makefile | 2 ++ drivers/firmware/efi/libstub/Makefile | 1 + kernel/Makefile | 1 + lib/Makefile | 1 + 10 files changed, 19 insertions(+) diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index e2839b5c246c..c039abd4c81f 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -10,6 +10,8 @@ # KASAN_SANITIZE := n +# KMSAN doesn't work for i386 +KMSAN_SANITIZE := n OBJECT_FILES_NON_STANDARD := y # Kernel does not boot with kcov instrumentation here. diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 6b84afdd7538..9efe2d9fca4c 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -18,6 +18,8 @@ # compressed vmlinux.bin.all + u32 size of vmlinux.bin.all KASAN_SANITIZE := n +# KMSAN doesn't work for i386 +KMSAN_SANITIZE := n OBJECT_FILES_NON_STANDARD := y # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 0f2154106d01..000467a1a4f2 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -11,6 +11,9 @@ include $(srctree)/lib/vdso/Makefile KBUILD_CFLAGS += $(DISABLE_LTO) KASAN_SANITIZE := n +# Undefined references to KMSAN hooks. +KMSAN_SANITIZE_vclock_gettime.o := n +KMSAN_SANITIZE_vgetcpu.o := n UBSAN_SANITIZE := n OBJECT_FILES_NON_STANDARD := y diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 3578ad248bc9..ce39972a7edf 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -28,6 +28,10 @@ KASAN_SANITIZE_dumpstack_$(BITS).o := n KASAN_SANITIZE_stacktrace.o := n KASAN_SANITIZE_paravirt.o := n +# Work around reboot loop. +KMSAN_SANITIZE_head$(BITS).o := n +KMSAN_SANITIZE_nmi.o := n + OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y OBJECT_FILES_NON_STANDARD_test_nx.o := y OBJECT_FILES_NON_STANDARD_paravirt_patch.o := y diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index d7a1e5a9331c..41f4f8f2f2f0 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -12,6 +12,7 @@ endif # If these files are instrumented, boot hangs during the first second. KCOV_INSTRUMENT_common.o := n KCOV_INSTRUMENT_perf_event.o := n +KMSAN_SANITIZE_common.o := n # Make sure load_percpu_segment has no stackprotector nostackp := $(call cc-option, -fno-stack-protector) diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 84373dc9b341..42cb3a6409b0 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -7,6 +7,8 @@ KCOV_INSTRUMENT_mem_encrypt_identity.o := n KASAN_SANITIZE_mem_encrypt.o := n KASAN_SANITIZE_mem_encrypt_identity.o := n +KMSAN_SANITIZE_cpu_entry_area.o := n + ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_mem_encrypt.o = -pg CFLAGS_REMOVE_mem_encrypt_identity.o = -pg diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index f60501a384f9..27e7bc0bbdde 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile @@ -7,6 +7,8 @@ # # KASAN_SANITIZE := n +# KMSAN doesn't work for i386 +KMSAN_SANITIZE := n OBJECT_FILES_NON_STANDARD := y # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 0460c7581220..11869c17a64c 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -32,6 +32,7 @@ KBUILD_CFLAGS := $(cflags-y) -DDISABLE_BRANCH_PROFILING \ GCOV_PROFILE := n KASAN_SANITIZE := n +KMSAN_SANITIZE := n UBSAN_SANITIZE := n OBJECT_FILES_NON_STANDARD := y diff --git a/kernel/Makefile b/kernel/Makefile index daad787fb795..5fd6fbca2592 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -30,6 +30,7 @@ KCOV_INSTRUMENT_extable.o := n # Don't self-instrument. KCOV_INSTRUMENT_kcov.o := n KASAN_SANITIZE_kcov.o := n +KMSAN_SANITIZE_kcov.o := n CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector) # cond_syscall is currently not LTO compatible diff --git a/lib/Makefile b/lib/Makefile index cb44262c38ee..a96d1d6e6a34 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -218,6 +218,7 @@ obj-$(CONFIG_IRQ_POLL) += irq_poll.o obj-$(CONFIG_STACKDEPOT) += stackdepot.o KASAN_SANITIZE_stackdepot.o := n +KMSAN_SANITIZE_stackdepot.o := n KCOV_INSTRUMENT_stackdepot.o := n libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \ From patchwork Fri Oct 18 09:42:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11198001 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C075113B1 for ; Fri, 18 Oct 2019 09:44:10 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 83D2020820 for ; Fri, 18 Oct 2019 09:44:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="J2WCHWzm" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 83D2020820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 6F5DE8E002D; Fri, 18 Oct 2019 05:44:08 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 6A81E8E0003; Fri, 18 Oct 2019 05:44:08 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 594FF8E002D; Fri, 18 Oct 2019 05:44:08 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0109.hostedemail.com [216.40.44.109]) by kanga.kvack.org (Postfix) with ESMTP id 30F918E0003 for ; Fri, 18 Oct 2019 05:44:08 -0400 (EDT) Received: from smtpin14.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with SMTP id C6FAEEFB8 for ; Fri, 18 Oct 2019 09:44:07 +0000 (UTC) X-FDA: 76056419334.14.deer47_7b4e08c9c2e27 X-Spam-Summary: 2,0,0,b0e4dfe231ede290,d41d8cd98f00b204,3zompxqykcbmz41wxaz77z4x.v75416dg-553etv3.7az@flex--glider.bounces.google.com,:glider@google.com:akpm@linux-foundation.org:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:2:41:152:355:379:541:800:960:966:968:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1535:1593:1594:1605:1606:1730:1747:1777:1792:2194:2196:2198:2199:2200:2201:2393:2553:2559:2562:2693:2731:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:3872:3874:4119:4250:4321:4385:5007:6119:6120:6261:6653:7875:7901:7903:7904:8603:8660:9592:9969:10004:11026:11232:11473:11657:11658:11914:12043:12291:12296:12297:12438:12555:12683:12895:12986:13148:13230:13846:14096:14097:14394:14659:21080:21212:21365:21444:21451:21611:21627:21740:21966:30012:30029:30054:30055:30062:30064:30070:30090,0,RBL:209.85.128.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCac he:0,MSF X-HE-Tag: deer47_7b4e08c9c2e27 X-Filterd-Recvd-Size: 8547 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf02.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:07 +0000 (UTC) Received: by mail-wm1-f73.google.com with SMTP id l184so928341wmf.6 for ; Fri, 18 Oct 2019 02:44:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Vasm+6WQlcurV54BG5ONxEH4GDxu9i5ZUwZTO8dWfq0=; b=J2WCHWzmVVMQLS1RcLEL8bAYf5B9KJpTW8sfYE1j5zUZemeeL5Tdm+EaahEvtOwEMc KItJKPXYpdKzbvzciZMKALP8xKSpCqtNdAoLUs9bpz8nUWldvT3pqof74Zx9QERre7Zu kTSTVkEF5wOoXq+E5Qr9Lgg2jZqkVdu7Iw2vLw9rqrnq2dSFZ0okhw/4GIzENCc3xFW/ 0KgwM0s1tM0/lWIJWp5bTqJoNDZYDUjYl12HM2Qur5ETBYMcJhFGz6MdaK/qfL4jTSnl Yb8OFGo6JWBWGFEheewlokGAnMp1nTxMtBzB+OgNIzzhlr7BgPFfHIo51wVA/X0qUqt+ 432g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Vasm+6WQlcurV54BG5ONxEH4GDxu9i5ZUwZTO8dWfq0=; b=tUM/B5EuI68eKFMYYWgrJj02sneqL1TFFEALOD3oggxVkcRIXS8EYlaFGd4nuvHsN4 cpnssjbXWVsooubOM8IKYxe3jh88XqxysuW2zeX4kT+5ewzoWHuJ4yaISYfzUoSXxlzN CAcTcfhqGi4MgK+VyuZOt86qUIMW4yc7LMxVaM3qyNuYshaQ879FOHRom9kFE5SIiCm4 bWHdjkGAnheSfogLcjTZVClhjuboASOmVQMVCQc7c3V9CVc9ovzBGSKTZFzN83ggrtZx x8ost782BN3TJlgGKzd//7pmIj8l3FueAdAV7KbdAKxYEpJ6L/vHbGjKLMtr4CbL2Wjb joQQ== X-Gm-Message-State: APjAAAXQQv6DmPEBMgQOFz8DCC05oGKvqH3V+aTVRVxvBz1irX89q6lU f4FkiVYK2j5QdUDs5JlhPRY/X4bFke0= X-Google-Smtp-Source: APXvYqwNIBr0Zabn63fCWF6pyd1cMBhmB6hr9DUzshyIFRNrwpKErjkjvjFV6sY6IN3G8ZAKBlwp1QTRBAo= X-Received: by 2002:adf:ef0f:: with SMTP id e15mr7291869wro.312.1571391846092; Fri, 18 Oct 2019 02:44:06 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:56 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-19-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 18/26] kmsan: mm: call KMSAN hooks from SLUB code From: glider@google.com To: Alexander Potapenko Cc: Andrew Morton , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: In order to report uninitialized memory coming from heap allocations KMSAN has to poison them unless they're created with __GFP_ZERO. It's handy that we need KMSAN hooks in the places where init_on_alloc/init_on_free initialization is performed. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Andrew Morton Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I51103b7981d3aabed747d0c85cbdc85568665871 --- mm/slub.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 3d63ae320d31..3d6d4c63446e 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include /* KMSAN_INIT_VALUE */ #include #include #include @@ -285,17 +287,27 @@ static void prefetch_freepointer(const struct kmem_cache *s, void *object) prefetch(object + s->offset); } +/* + * When running under KMSAN, get_freepointer_safe() may return an uninitialized + * pointer value in the case the current thread loses the race for the next + * memory chunk in the freelist. In that case this_cpu_cmpxchg_double() in + * slab_alloc_node() will fail, so the uninitialized value won't be used, but + * KMSAN will still check all arguments of cmpxchg because of imperfect + * handling of inline assembly. + * To work around this problem, use KMSAN_INIT_VALUE() to force initialize the + * return value of get_freepointer_safe(). + */ static inline void *get_freepointer_safe(struct kmem_cache *s, void *object) { unsigned long freepointer_addr; void *p; if (!debug_pagealloc_enabled()) - return get_freepointer(s, object); + return KMSAN_INIT_VALUE(get_freepointer(s, object)); freepointer_addr = (unsigned long)object + s->offset; probe_kernel_read(&p, (void **)freepointer_addr, sizeof(p)); - return freelist_ptr(s, p, freepointer_addr); + return KMSAN_INIT_VALUE(freelist_ptr(s, p, freepointer_addr)); } static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) @@ -1390,6 +1402,7 @@ static inline void *kmalloc_large_node_hook(void *ptr, size_t size, gfp_t flags) ptr = kasan_kmalloc_large(ptr, size, flags); /* As ptr might get tagged, call kmemleak hook after KASAN. */ kmemleak_alloc(ptr, size, 1, flags); + kmsan_kmalloc_large(ptr, size, flags); return ptr; } @@ -1397,6 +1410,7 @@ static __always_inline void kfree_hook(void *x) { kmemleak_free(x); kasan_kfree_large(x, _RET_IP_); + kmsan_kfree_large(x); } static __always_inline bool slab_free_hook(struct kmem_cache *s, void *x) @@ -1453,6 +1467,12 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s, } while (object != old_tail); } + do { + object = next; + next = get_freepointer(s, object); + kmsan_slab_free(s, 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. @@ -2769,6 +2789,7 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s, if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object) memset(object, 0, s->object_size); + kmsan_slab_alloc(s, object, gfpflags); slab_post_alloc_hook(s, gfpflags, 1, &object); return object; @@ -2797,6 +2818,7 @@ void *kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size) void *ret = slab_alloc(s, gfpflags, _RET_IP_); trace_kmalloc(_RET_IP_, ret, size, s->size, gfpflags); ret = kasan_kmalloc(s, ret, size, gfpflags); + return ret; } EXPORT_SYMBOL(kmem_cache_alloc_trace); @@ -2809,7 +2831,6 @@ void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) trace_kmem_cache_alloc_node(_RET_IP_, ret, s->object_size, s->size, gfpflags, node); - return ret; } EXPORT_SYMBOL(kmem_cache_alloc_node); @@ -2825,6 +2846,7 @@ void *kmem_cache_alloc_node_trace(struct kmem_cache *s, size, s->size, gfpflags, node); ret = kasan_kmalloc(s, ret, size, gfpflags); + return ret; } EXPORT_SYMBOL(kmem_cache_alloc_node_trace); @@ -3150,7 +3172,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, void **p) { struct kmem_cache_cpu *c; - int i; + int i, j; /* memcg and kmem_cache debug support */ s = slab_pre_alloc_hook(s, flags); @@ -3188,11 +3210,11 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, /* Clear memory outside IRQ disabled fastpath loop */ if (unlikely(slab_want_init_on_alloc(flags, s))) { - int j; - for (j = 0; j < i; j++) memset(p[j], 0, s->object_size); } + for (j = 0; j < i; j++) + kmsan_slab_alloc(s, p[j], flags); /* memcg and kmem_cache debug support */ slab_post_alloc_hook(s, flags, size, p); @@ -3793,6 +3815,7 @@ static int __init setup_slub_min_objects(char *str) __setup("slub_min_objects=", setup_slub_min_objects); +__no_sanitize_memory void *__kmalloc(size_t size, gfp_t flags) { struct kmem_cache *s; @@ -5698,6 +5721,7 @@ static char *create_unique_id(struct kmem_cache *s) p += sprintf(p, "%07u", s->size); BUG_ON(p > name + ID_STR_LENGTH - 1); + kmsan_unpoison_shadow(name, p - name); return name; } @@ -5847,6 +5871,7 @@ static int sysfs_slab_alias(struct kmem_cache *s, const char *name) al->name = name; al->next = alias_list; alias_list = al; + kmsan_unpoison_shadow(al, sizeof(struct saved_alias)); return 0; } From patchwork Fri Oct 18 09:42:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11198003 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A5D8214ED for ; Fri, 18 Oct 2019 09:44:13 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 4B47C20820 for ; Fri, 18 Oct 2019 09:44:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="BgCwpy6f" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4B47C20820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id B63E18E002E; Fri, 18 Oct 2019 05:44:11 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id B3DA88E0003; Fri, 18 Oct 2019 05:44:11 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 93EED8E002E; Fri, 18 Oct 2019 05:44:11 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0038.hostedemail.com [216.40.44.38]) by kanga.kvack.org (Postfix) with ESMTP id 6A1468E0003 for ; Fri, 18 Oct 2019 05:44:11 -0400 (EDT) Received: from smtpin22.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with SMTP id 0F1C418238CBE for ; Fri, 18 Oct 2019 09:44:11 +0000 (UTC) X-FDA: 76056419502.22.foot77_7bbeedc90cd3a X-Spam-Summary: 2,0,0,98ab9802c26ce933,d41d8cd98f00b204,3aympxqykcby274z0d2aa270.ya8749gj-886hwy6.ad2@flex--glider.bounces.google.com,:glider@google.com:akpm@linux-foundation.org:gregkh@linuxfoundation.org:edumazet@google.com:wsa@the-dreams.de:pmladek@suse.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:305:327:355:379:541:800:960:966:968:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1593:1594:1605:1730:1747:1777:1792:1801:1981:2194:2196:2198:2199:2200:2201:2393:2538:2553:2559:2562:2693:2731:2892:2896:2904:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:3872:3874:4250:4321:4385:4605:5007:6117:6119:6120:6261:6653:7774:7875:7901:7903:8660:8957:9010:9969:10004:11026:11232:11473:11657:11658:11914:12043:12291:12296:12297:12438:12555:12691:12737:12895:12986:13148:13153:13228:13230:13846:14096:14097:14394:14659:21080:21212:21324:21365:21433:21444:21450:21451:21611:21627:21740:21795:21809:30003:30012:30045:30051:30054:30064:30067:30070:30 075:3007 X-HE-Tag: foot77_7bbeedc90cd3a X-Filterd-Recvd-Size: 20048 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf30.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:10 +0000 (UTC) Received: by mail-wr1-f73.google.com with SMTP id v7so415403wrf.4 for ; Fri, 18 Oct 2019 02:44:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=n5XdqwVX8lXa3z5Hhmg6mwU44EVU6s0aPKu014KvQ5Y=; b=BgCwpy6fOqdJvU+ywXxsNdiKyyMCvcp1Y9uaNaeN3i/S5J1bB6Tk/x0pXvCj/M9qkL UHgckGmDSD93kz6tG3ydZm6DT93SFm82jt/flMkBZrM3LuyY1sOnEGj7amzGN0yjJmAi jnO7cKOI3DiVfEQBb4iJbHXgMGwGsRbnbYkix/wF9uD4EgE1cSH2V6qL37QisJWOi4oZ vpT9/BDv8csW4cBmTm0z6+5AXxuIzqU+o74c9ZH7ADDEecqli4AEdZYSag8MZBlSjrUc 0bDeCcDiW6Hbr2stjsUwyGRfPQdeUb752SlSyDru6s3xeaRl/lCtJtw+fUmNJa6bwyx8 18Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=n5XdqwVX8lXa3z5Hhmg6mwU44EVU6s0aPKu014KvQ5Y=; b=j2Wqkfb2nKOfvRaqIgjXaFom+ljMT8mnnpkyXyoU76SocbYun8FffQRBVETzmMNl4+ V4A3hyy/+nsqcezGjiGFIEEJVDuLKChT30tO23nPCjHZFWQsxklFD20abWds/NNn/dAm zjjehI2X9/CcnRa6IYw8uH4GlEaJaWW3EPyYI22nvWFWDjzv9bTS5Gbe/zQzNjFqvGTs sGPo32OKE0dPpfRDz4HXnuN5bmrm11R+9Qy2wUEXrxEHzk8ZsR6Skztb6yxqwc/RiCnq ABh0xMOTKyltw8DmRT/YrOX0uf5fXcQwp/LPGup7EpvEuBMrVEeUzsaPbuB7UDTIqCKj 0hqQ== X-Gm-Message-State: APjAAAVo2IUiSH57u9L3eBpMGtBGKA2tVJvuF0eq3lJ4vucRCNwC4xA1 /EPuGt6KPWTlcWIpOXElhoqZtRLIA6A= X-Google-Smtp-Source: APXvYqwcKZoJwREwnTrmIMeBaJ8nuYhgDl/atijIeArHsCB1xMjeDwtVxO/UzpLceagy/rwYFXcVsZ72Bgk= X-Received: by 2002:adf:f004:: with SMTP id j4mr7563009wro.68.1571391849101; Fri, 18 Oct 2019 02:44:09 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:57 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-20-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 19/26] kmsan: call KMSAN hooks where needed From: glider@google.com To: Alexander Potapenko Cc: Andrew Morton , Greg Kroah-Hartman , Eric Dumazet , Wolfram Sang , Petr Mladek , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Insert KMSAN hooks that check for potential memory errors and/or make necessary bookkeeping changes: - allocate/split/deallocate metadata pages in alloc_pages()/split_page()/free_page(); - clear page shadow and origins in clear_page(), copy_user_highpage(); - copy page metadata in copy_highpage(), wp_page_copy(); - handle vmap()/vunmap()/iounmap(); - handle task creation and deletion; - handle vprintk(); - call softirq entry/exit hooks in kernel/softirq.c; - check/initialize memory sent to/read from USB, I2C, and network Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Andrew Morton Cc: Greg Kroah-Hartman Cc: Eric Dumazet Cc: Wolfram Sang Cc: Petr Mladek Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I1250a928d9263bf71fdaa067a070bdee686ef47b --- arch/x86/include/asm/page_64.h | 13 +++++++++++++ arch/x86/mm/ioremap.c | 3 +++ drivers/i2c/i2c-core-base.c | 2 ++ drivers/usb/core/urb.c | 2 ++ include/linux/highmem.h | 4 ++++ kernel/exit.c | 2 ++ kernel/fork.c | 2 ++ kernel/kthread.c | 2 ++ kernel/printk/printk.c | 8 +++++++- kernel/softirq.c | 5 +++++ lib/ioremap.c | 5 +++++ mm/compaction.c | 9 +++++++++ mm/gup.c | 3 +++ mm/memory.c | 2 ++ mm/page_alloc.c | 16 ++++++++++++++++ mm/vmalloc.c | 23 +++++++++++++++++++++-- net/sched/sch_generic.c | 2 ++ 17 files changed, 100 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index 939b1cff4a7b..0ba43d93414f 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h @@ -44,14 +44,27 @@ void clear_page_orig(void *page); void clear_page_rep(void *page); void clear_page_erms(void *page); +/* This is an assembly header, avoid including too much of kmsan.h */ +#ifdef CONFIG_KMSAN +void kmsan_clear_page(void *page_addr); +#endif +__no_sanitize_memory static inline void clear_page(void *page) { +#ifdef CONFIG_KMSAN + /* alternative_call_2() changes |page|. */ + void *page_copy = page; +#endif alternative_call_2(clear_page_orig, clear_page_rep, X86_FEATURE_REP_GOOD, clear_page_erms, X86_FEATURE_ERMS, "=D" (page), "0" (page) : "cc", "memory", "rax", "rcx"); +#ifdef CONFIG_KMSAN + /* Clear KMSAN shadow for the pages that have it. */ + kmsan_clear_page(page_copy); +#endif } void copy_page(void *to, void *from); diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index a39dcdb5ae34..fdb2abc11a82 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -7,6 +7,7 @@ * (C) Copyright 1995 1996 Linus Torvalds */ +#include #include #include #include @@ -451,6 +452,8 @@ void iounmap(volatile void __iomem *addr) return; } + kmsan_iounmap_page_range((unsigned long)addr, + (unsigned long)addr + get_vm_area_size(p)); free_memtype(p->phys_addr, p->phys_addr + get_vm_area_size(p)); /* Finally remove it */ diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 5f6a4985f2bc..9685d3399c79 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -1975,6 +1976,7 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) trace_i2c_write(adap, &msgs[i], i); } + kmsan_handle_i2c_transfer(msgs, num); /* Retry automatically on arbitration loss */ orig_jiffies = jiffies; for (ret = 0, try = 0; try <= adap->retries; try++) { diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 0eab79f82ce4..5bdb54d71c2e 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -401,6 +402,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL | URB_DMA_SG_COMBINED); urb->transfer_flags |= (is_out ? URB_DIR_OUT : URB_DIR_IN); + kmsan_handle_urb(urb, is_out); if (xfertype != USB_ENDPOINT_XFER_CONTROL && dev->state < USB_STATE_CONFIGURED) diff --git a/include/linux/highmem.h b/include/linux/highmem.h index ea5cdbd8c2c3..623b56f48685 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -255,6 +256,8 @@ static inline void copy_user_highpage(struct page *to, struct page *from, vfrom = kmap_atomic(from); vto = kmap_atomic(to); copy_user_page(vto, vfrom, vaddr, to); + /* User pages don't have shadow, just clear the destination. */ + kmsan_clear_page(page_address(to)); kunmap_atomic(vto); kunmap_atomic(vfrom); } @@ -270,6 +273,7 @@ static inline void copy_highpage(struct page *to, struct page *from) vfrom = kmap_atomic(from); vto = kmap_atomic(to); copy_page(vto, vfrom); + kmsan_copy_page_meta(to, from); kunmap_atomic(vto); kunmap_atomic(vfrom); } diff --git a/kernel/exit.c b/kernel/exit.c index a46a50d67002..9e3ce929110b 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -719,6 +720,7 @@ void __noreturn do_exit(long code) profile_task_exit(tsk); kcov_task_exit(tsk); + kmsan_task_exit(tsk); WARN_ON(blk_needs_flush_plug(tsk)); diff --git a/kernel/fork.c b/kernel/fork.c index bcdf53125210..0f08952a42dc 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -931,6 +932,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) account_kernel_stack(tsk, 1); kcov_task_init(tsk); + kmsan_task_create(tsk); #ifdef CONFIG_FAULT_INJECTION tsk->fail_nth = 0; diff --git a/kernel/kthread.c b/kernel/kthread.c index 621467c33fef..9b948559a34a 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -350,6 +351,7 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data), set_cpus_allowed_ptr(task, cpu_all_mask); } kfree(create); + kmsan_task_create(task); return task; } diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index ca65327a6de8..f77fdcb5f861 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1914,7 +1914,12 @@ int vprintk_store(int facility, int level, * The printf needs to come first; we need the syslog * prefix which might be passed-in as a parameter. */ - text_len = vscnprintf(text, sizeof(textbuf), fmt, args); + /* + * We've checked the printk arguments in vprintk_emit() already. + * Initialize |text_len| to prevent the errors from spreading. + */ + text_len = KMSAN_INIT_VALUE(vscnprintf(text, sizeof(textbuf), fmt, + args)); /* mark and strip a trailing newline */ if (text_len && text[text_len-1] == '\n') { @@ -1972,6 +1977,7 @@ asmlinkage int vprintk_emit(int facility, int level, boot_delay_msec(level); printk_delay(); + kmsan_handle_vprintk(&fmt, args); /* This stops the holder of console_sem just where we want him */ logbuf_lock_irqsave(flags); curr_log_seq = log_next_seq; diff --git a/kernel/softirq.c b/kernel/softirq.c index 0427a86743a4..6d566dd68b35 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -370,7 +371,9 @@ static inline void invoke_softirq(void) * it is the irq stack, because it should be near empty * at this stage. */ + kmsan_softirq_enter(); __do_softirq(); + kmsan_softirq_exit(); #else /* * Otherwise, irq_exit() is called on the task stack that can @@ -600,7 +603,9 @@ static void run_ksoftirqd(unsigned int cpu) * We can safely run softirq on inline stack, as we are not deep * in the task stack here. */ + kmsan_softirq_enter(); __do_softirq(); + kmsan_softirq_exit(); local_irq_enable(); cond_resched(); return; diff --git a/lib/ioremap.c b/lib/ioremap.c index 0a2ffadc6d71..5f830cee5bfc 100644 --- a/lib/ioremap.c +++ b/lib/ioremap.c @@ -6,6 +6,7 @@ * * (C) Copyright 1995 1996 Linus Torvalds */ +#include #include #include #include @@ -214,6 +215,8 @@ int ioremap_page_range(unsigned long addr, unsigned long start; unsigned long next; int err; + unsigned long old_addr = addr; + phys_addr_t old_phys_addr = phys_addr; might_sleep(); BUG_ON(addr >= end); @@ -228,6 +231,8 @@ int ioremap_page_range(unsigned long addr, } while (pgd++, phys_addr += (next - addr), addr = next, addr != end); flush_cache_vmap(start, end); + if (!err) + kmsan_ioremap_page_range(old_addr, end, old_phys_addr, prot); return err; } diff --git a/mm/compaction.c b/mm/compaction.c index ce08b39d85d4..e9a5898e5fe0 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -84,6 +84,15 @@ static void split_map_pages(struct list_head *list) for (i = 0; i < nr_pages; i++) { list_add(&page->lru, &tmp_list); +#ifdef CONFIG_KMSAN + /* + * TODO(glider): we may lose the metadata when copying + * something to these pages. Need to allocate shadow + * and origin pages here instead. + */ + page->shadow = NULL; + page->origin = NULL; +#endif page++; } } diff --git a/mm/gup.c b/mm/gup.c index 23a9f9c9d377..c16e4288997d 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -2347,6 +2348,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, gup_fast_permitted(start, end)) { local_irq_save(flags); gup_pgd_range(start, end, write ? FOLL_WRITE : 0, pages, &nr); + kmsan_gup_pgd_range(pages, nr); local_irq_restore(flags); } @@ -2416,6 +2418,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, gup_fast_permitted(start, end)) { local_irq_disable(); gup_pgd_range(addr, end, gup_flags, pages, &nr); + kmsan_gup_pgd_range(pages, nr); local_irq_enable(); ret = nr; } diff --git a/mm/memory.c b/mm/memory.c index b1ca51a079f2..48ceacc06e2d 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -2328,6 +2329,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) if (!new_page) goto oom; cow_user_page(new_page, old_page, vmf->address, vma); + kmsan_copy_page_meta(new_page, old_page); } if (mem_cgroup_try_charge_delay(new_page, mm, GFP_KERNEL, &memcg, false)) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c0b2e0306720..f52494e0dcd9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include #include @@ -1133,6 +1135,7 @@ static __always_inline bool free_pages_prepare(struct page *page, VM_BUG_ON_PAGE(PageTail(page), page); trace_mm_page_free(page, order); + kmsan_free_page(page, order); /* * Check tail pages before head page information is cleared to @@ -3121,6 +3124,7 @@ void split_page(struct page *page, unsigned int order) VM_BUG_ON_PAGE(PageCompound(page), page); VM_BUG_ON_PAGE(!page_count(page), page); + kmsan_split_page(page, order); for (i = 1; i < (1 << order); i++) set_page_refcounted(page + i); split_page_owner(page, order); @@ -3253,6 +3257,13 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone, /* * Allocate a page from the given zone. Use pcplists for order-0 allocations. */ +/* + * TODO(glider): rmqueue() may call __msan_poison_alloca() through a call to + * set_pfnblock_flags_mask(). If __msan_poison_alloca() attempts to allocate + * pages for the stack depot, it may call rmqueue() again, which will result + * in a deadlock. + */ +__no_sanitize_memory static inline struct page *rmqueue(struct zone *preferred_zone, struct zone *zone, unsigned int order, @@ -4779,6 +4790,11 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid, trace_mm_page_alloc(page, order, alloc_mask, ac.migratetype); + if (page) + if (kmsan_alloc_page(page, order, gfp_mask)) { + __free_pages(page, order); + page = NULL; + } return page; } EXPORT_SYMBOL(__alloc_pages_nodemask); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index a3c70e275f4e..bdf66ffcf02c 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -119,7 +120,8 @@ static void vunmap_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end) } while (p4d++, addr = next, addr != end); } -static void vunmap_page_range(unsigned long addr, unsigned long end) +/* Exported for KMSAN, visible in mm/kmsan/kmsan.h only. */ +void __vunmap_page_range(unsigned long addr, unsigned long end) { pgd_t *pgd; unsigned long next; @@ -133,6 +135,12 @@ static void vunmap_page_range(unsigned long addr, unsigned long end) vunmap_p4d_range(pgd, addr, next); } while (pgd++, addr = next, addr != end); } +EXPORT_SYMBOL(__vunmap_page_range); +static void vunmap_page_range(unsigned long addr, unsigned long end) +{ + kmsan_vunmap_page_range(addr, end); + __vunmap_page_range(addr, end); +} static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, pgprot_t prot, struct page **pages, int *nr) @@ -216,8 +224,11 @@ static int vmap_p4d_range(pgd_t *pgd, unsigned long addr, * will have pfns corresponding to the "pages" array. * * Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N] + * + * This function is exported for use in KMSAN, but is only declared in KMSAN + * headers. */ -static int vmap_page_range_noflush(unsigned long start, unsigned long end, +int __vmap_page_range_noflush(unsigned long start, unsigned long end, pgprot_t prot, struct page **pages) { pgd_t *pgd; @@ -237,6 +248,14 @@ static int vmap_page_range_noflush(unsigned long start, unsigned long end, return nr; } +EXPORT_SYMBOL(__vmap_page_range_noflush); + +static int vmap_page_range_noflush(unsigned long start, unsigned long end, + pgprot_t prot, struct page **pages) +{ + kmsan_vmap_page_range_noflush(start, end, prot, pages); + return __vmap_page_range_noflush(start, end, prot, pages); +} static int vmap_page_range(unsigned long start, unsigned long end, pgprot_t prot, struct page **pages) diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 17bd8f539bc7..fd22c4a4ba42 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -659,6 +660,7 @@ static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc) } else { qdisc->empty = true; } + kmsan_check_skb(skb); return skb; } From patchwork Fri Oct 18 09:42:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11198005 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 87E2614ED for ; Fri, 18 Oct 2019 09:44:16 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 3930120820 for ; Fri, 18 Oct 2019 09:44:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="nVsd/7GZ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3930120820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id A2BAB8E002F; Fri, 18 Oct 2019 05:44:14 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 9B3618E0003; Fri, 18 Oct 2019 05:44:14 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8C9398E002F; Fri, 18 Oct 2019 05:44:14 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0201.hostedemail.com [216.40.44.201]) by kanga.kvack.org (Postfix) with ESMTP id 6B3268E0003 for ; Fri, 18 Oct 2019 05:44:14 -0400 (EDT) Received: from smtpin22.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with SMTP id 18CE81833A387 for ; Fri, 18 Oct 2019 09:44:14 +0000 (UTC) X-FDA: 76056419628.22.steam76_7c309015b5847 X-Spam-Summary: 2,0,0,dc3638953bbfb999,d41d8cd98f00b204,3bimpxqykcbk5a723g5dd5a3.1dba7cjm-bb9kz19.dg5@flex--glider.bounces.google.com,:glider@google.com:tglx@linutronix.de:akpm@linux-foundation.org:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:1:2:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1593:1594:1605:1730:1747:1777:1792:1801:2194:2199:2393:2553:2559:2562:2904:3138:3139:3140:3141:3142:3152:3165:3865:3866:3867:3868:3870:3871:3872:3874:4052:4250:4321:4605:5007:6119:6120:6261:6653:7774:7901:7903:7974:8660:9040:9969:11026:11232:11473:11657:11658:11914:12043:12296:12297:12438:12555:12895:12986:13148:13230:13846:13972:14096:14097:14394:14659:21080:21325:21365:21433:21444:21451:21611:21618:21795:21966:30012:30029:30045:30051:30054:30064:30075:30079:30090,0,RBL:209.85.221.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.175.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bu lk,SPF:f X-HE-Tag: steam76_7c309015b5847 X-Filterd-Recvd-Size: 12205 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf44.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:13 +0000 (UTC) Received: by mail-wr1-f73.google.com with SMTP id 67so2337820wrm.18 for ; Fri, 18 Oct 2019 02:44:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=pIdz3x8cMAyK43UPY4qmclMLWD5VH7R63+cqj8NLHSY=; b=nVsd/7GZWrAF/GMFP65yjViKbDKwTNUh2zUjbJo8cQ6r+yTqb2371eSpQony/hXz0K UmJ70SJtnp3jWiQrfQAlu1IlA4Pk/YKd7RV99efreQeHcVNyqMcBH1VhqDgtOeTPf6lZ uSL8ztnBiMmrhPeCc1/VX2ukHcwVZi5ipFoGGlCgQFOOpe+KwPD7IeZIzT6HVyi87BX6 DAdte/Le6iRu/a5eLAZZbQiJMLXO6DhXpBp3zWjfPC9bZ+YlWVKfQLILFyJo6yZ7M6Ps BUgmtvq6gVHyeloVWR1PCqQnFLrkVIiuIEIFpAboXGRqihtDaMWGO2xaXH9pX+OrC1+n uHXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=pIdz3x8cMAyK43UPY4qmclMLWD5VH7R63+cqj8NLHSY=; b=LPZ5fFp07GzSVTtcEouzugYMDam1AR1LOzMYNEIPtuHPYvRAE25eaNujhRYsJdO3DK tDNpF36/t+fynzlSqu2f+i0GgvQiknP1cy0gx/Govzpm44KBL0OJUAFNyt2GIk2IyX+U BLMBeneSEPop1T3hrbIUYd1X4Rl/iqR9Mx6mhuhmlgDMzeF+Dpaj0O7AWB1KxWhwQAdj t6FlDt4ZE4fFw3uVxuw8NCdT4s91aanO0K3ij/iL4dd6eq44aDA3d+6vZCXczVG4IPNs cdVbcgWOBqw1VhEaOWCPgfyjnReOUBE1m56WjjAMQIoIbxYN/4dAGr6nj6KDnvSN3uB5 PKBw== X-Gm-Message-State: APjAAAVzVyDtQhmVUZvI3QzbdLg+iCbGP5UXmgrF5PISuMiLpOWkb/XR r/KOp01Ap4TMj/vbXnbGT6yuc3B9e3E= X-Google-Smtp-Source: APXvYqyump5TE9t7gzzwPyZAg/gm2iZb1lG5Gbd/75jKjHxjg52xSZqoNoKvpd+JVR4+KtmURwA0GO8ikrE= X-Received: by 2002:adf:bd8f:: with SMTP id l15mr6825618wrh.362.1571391852125; Fri, 18 Oct 2019 02:44:12 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:58 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-21-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 20/26] kmsan: disable instrumentation of certain functions From: glider@google.com To: Alexander Potapenko Cc: Thomas Gleixner , Andrew Morton , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Some functions are called from handwritten assembly, and therefore don't have their arguments' metadata fully set up by the instrumentation code. Mark them with __no_sanitize_memory to avoid false positives from spreading further. Certain functions perform task switching, so that the value of |current| is different as they proceed. Because KMSAN state pointer is only read once at the beginning of the function, touching it after |current| has changed may be dangerous. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Thomas Gleixner Cc: Andrew Morton Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I684d23dac5a22eb0a4cea71993cb934302b17cea --- arch/x86/entry/common.c | 1 + arch/x86/include/asm/irq_regs.h | 1 + arch/x86/include/asm/syscall_wrapper.h | 1 + arch/x86/kernel/apic/apic.c | 2 ++ arch/x86/kernel/dumpstack_64.c | 1 + arch/x86/kernel/process_64.c | 5 +++++ arch/x86/kernel/traps.c | 12 ++++++++++-- arch/x86/kernel/uprobes.c | 7 ++++++- kernel/profile.c | 1 + kernel/sched/core.c | 11 +++++++++++ 10 files changed, 39 insertions(+), 3 deletions(-) diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 3f8e22615812..0dd5b2acb355 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -275,6 +275,7 @@ __visible inline void syscall_return_slowpath(struct pt_regs *regs) } #ifdef CONFIG_X86_64 +__no_sanitize_memory __visible void do_syscall_64(unsigned long nr, struct pt_regs *regs) { struct thread_info *ti; diff --git a/arch/x86/include/asm/irq_regs.h b/arch/x86/include/asm/irq_regs.h index 187ce59aea28..d65a00bd6f02 100644 --- a/arch/x86/include/asm/irq_regs.h +++ b/arch/x86/include/asm/irq_regs.h @@ -14,6 +14,7 @@ DECLARE_PER_CPU(struct pt_regs *, irq_regs); +__no_sanitize_memory static inline struct pt_regs *get_irq_regs(void) { return __this_cpu_read(irq_regs); diff --git a/arch/x86/include/asm/syscall_wrapper.h b/arch/x86/include/asm/syscall_wrapper.h index e046a405743d..43910ce1b53b 100644 --- a/arch/x86/include/asm/syscall_wrapper.h +++ b/arch/x86/include/asm/syscall_wrapper.h @@ -159,6 +159,7 @@ ALLOW_ERROR_INJECTION(__x64_sys##name, ERRNO); \ static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ + __no_sanitize_memory \ asmlinkage long __x64_sys##name(const struct pt_regs *regs) \ { \ return __se_sys##name(SC_X86_64_REGS_TO_ARGS(x,__VA_ARGS__));\ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 9e2dd2b296cd..43a1edd919ea 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1118,6 +1118,8 @@ static void local_apic_timer_interrupt(void) * [ if a single-CPU system runs an SMP kernel then we call the local * interrupt as well. Thus we cannot inline the local irq ... ] */ +/* TODO(glider): |regs| is uninitialized, so is |*regs|. */ +__no_sanitize_memory __visible void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 753b8cfe8b8a..ba883d282a43 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -143,6 +143,7 @@ static bool in_irq_stack(unsigned long *stack, struct stack_info *info) return true; } +__no_sanitize_memory int get_stack_info(unsigned long *stack, struct task_struct *task, struct stack_info *info, unsigned long *visit_mask) { diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index af64519b2695..27649ee3dbf8 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -500,6 +500,11 @@ void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp) * Kprobes not supported here. Set the probe on schedule instead. * Function graph tracer not supported too. */ +/* + * TODO(glider): __switch_to() does weird things with tasks, don't report + * anything here (also avoid touching the KMSAN state). + */ +__no_sanitize_memory __visible __notrace_funcgraph struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct *next_p) { diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 4bb0f8447112..a94282d1f60b 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -618,7 +618,10 @@ NOKPROBE_SYMBOL(do_int3); * Help handler running on a per-cpu (IST or entry trampoline) stack * to switch to the normal thread stack if the interrupted code was in * user mode. The actual stack switch is done in entry_64.S + * + * This function switches the registers - don't instrument it with KMSAN! */ +__no_sanitize_memory asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs) { struct pt_regs *regs = (struct pt_regs *)this_cpu_read(cpu_current_top_of_stack) - 1; @@ -634,6 +637,11 @@ struct bad_iret_stack { }; asmlinkage __visible notrace +/* + * Dark magic happening here, let's not instrument this function. + * Also avoid copying any metadata by using raw __memmove(). + */ +__no_sanitize_memory struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s) { /* @@ -648,10 +656,10 @@ struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s) (struct bad_iret_stack *)this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1; /* Copy the IRET target to the new stack. */ - memmove(&new_stack->regs.ip, (void *)s->regs.sp, 5*8); + __memmove(&new_stack->regs.ip, (void *)s->regs.sp, 5*8); /* Copy the remainder of the stack from the current stack. */ - memmove(new_stack, s, offsetof(struct bad_iret_stack, regs.ip)); + __memmove(new_stack, s, offsetof(struct bad_iret_stack, regs.ip)); BUG_ON(!user_mode(&new_stack->regs)); return new_stack; diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 8cd745ef8c7b..bcd4bf5a909f 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -8,6 +8,7 @@ * Jim Keniston */ #include +#include #include #include #include @@ -997,9 +998,13 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data) { struct die_args *args = data; - struct pt_regs *regs = args->regs; + struct pt_regs *regs; int ret = NOTIFY_DONE; + kmsan_unpoison_shadow(args, sizeof(*args)); + regs = args->regs; + if (regs) + kmsan_unpoison_shadow(regs, sizeof(*regs)); /* We are only interested in userspace traps */ if (regs && !user_mode(regs)) return NOTIFY_DONE; diff --git a/kernel/profile.c b/kernel/profile.c index af7c94bf5fa1..835a5b66d1a4 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -399,6 +399,7 @@ void profile_hits(int type, void *__pc, unsigned int nr_hits) } EXPORT_SYMBOL_GPL(profile_hits); +__no_sanitize_memory void profile_tick(int type) { struct pt_regs *regs = get_irq_regs(); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index dd05a378631a..951d19d217d7 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -475,6 +475,8 @@ void wake_q_add_safe(struct wake_q_head *head, struct task_struct *task) put_task_struct(task); } +/* TODO(glider): context switching here. */ +__no_sanitize_memory void wake_up_q(struct wake_q_head *head) { struct wake_q_node *node = head->first; @@ -3180,6 +3182,8 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev, * past. prev == current is still correct but we need to recalculate this_rq * because prev may have moved to another CPU. */ +/* TODO(glider): |current| changes here. */ +__no_sanitize_memory static struct rq *finish_task_switch(struct task_struct *prev) __releases(rq->lock) { @@ -3986,6 +3990,8 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) * * WARNING: must be called with preemption disabled! */ +/* TODO(glider): |current| changes here. */ +__no_sanitize_memory static void __sched notrace __schedule(bool preempt) { struct task_struct *prev, *next; @@ -4605,6 +4611,8 @@ int task_prio(const struct task_struct *p) * * Return: 1 if the CPU is currently idle. 0 otherwise. */ +/* TODO(glider): nothing to report here. */ +__no_sanitize_memory int idle_cpu(int cpu) { struct rq *rq = cpu_rq(cpu); @@ -6544,6 +6552,7 @@ static struct kmem_cache *task_group_cache __read_mostly; DECLARE_PER_CPU(cpumask_var_t, load_balance_mask); DECLARE_PER_CPU(cpumask_var_t, select_idle_mask); +__no_sanitize_memory void __init sched_init(void) { unsigned long ptr = 0; @@ -6716,6 +6725,8 @@ static inline int preempt_count_equals(int preempt_offset) return (nested == preempt_offset); } +/* TODO(glider): the args are most certainly initialized. */ +__no_sanitize_memory void __might_sleep(const char *file, int line, int preempt_offset) { /* From patchwork Fri Oct 18 09:42:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11198007 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1939913B1 for ; Fri, 18 Oct 2019 09:44:19 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id D062420820 for ; Fri, 18 Oct 2019 09:44:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="SgN5nIKf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D062420820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 436708E0030; Fri, 18 Oct 2019 05:44:17 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 3E75E8E0003; Fri, 18 Oct 2019 05:44:17 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 2D74D8E0030; Fri, 18 Oct 2019 05:44:17 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0191.hostedemail.com [216.40.44.191]) by kanga.kvack.org (Postfix) with ESMTP id F0C8B8E0003 for ; Fri, 18 Oct 2019 05:44:16 -0400 (EDT) Received: from smtpin19.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id 9A491A2D0 for ; Fri, 18 Oct 2019 09:44:16 +0000 (UTC) X-FDA: 76056419712.19.cloud05_7c9b55556e005 X-Spam-Summary: 2,0,0,6312909d98e03f17,d41d8cd98f00b204,3b4mpxqykcbw8da56j8gg8d6.4gedafmp-eecn24c.gj8@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:2393:2559:2562:2693:3138:3139:3140:3141:3142:3152:3352:3865:3867:3868:3870:3871:3872:4250:4321:5007:6120:6261:6653:7901:9969:10004:10400:11026:11232:11658:11914:12043:12114:12296:12297:12438:12555:12895:13069:13311:13357:13846:14181:14394:14659:14721:21080:21365:21444:21451:21627:30054:30064,0,RBL:error,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: cloud05_7c9b55556e005 X-Filterd-Recvd-Size: 4101 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf12.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:16 +0000 (UTC) Received: by mail-wr1-f73.google.com with SMTP id v7so415539wrf.4 for ; Fri, 18 Oct 2019 02:44:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=lKHqfOkwipsGh4+LNCETFHU5JmZXDTfRhV3V1uQ64Eg=; b=SgN5nIKfCdOq4l9YeBaMP2o1a0uvq1c1bmhVrXnBQUMyD52G8q3k+alvhZi+ukHMsh kA9p78D0WXpzunvDRoNfJhn5pRjnhkH3XHq91MpZUiU60bxgcwrvr2bb/hZv2n30YCzT PmUV7FpwZLbkJ3aT0n3f21Pnd6Zrby0eWoYGTWnSzyvUU28LhFl2vWxayFKBGJhcTloO oMocRbVLh1jSKJ/ledg3RrjRTGKdWL4+YGoCTMYoLNO5/Ai1q9niWNrkYzYKZ4LDY9Q8 VyCkBq3PPaW1q2UQ6FUJpHi0kG7i8UtG+5WoEPbPYmslGW58n9bwtHs9RlHo+/Hj9kIz gX3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=lKHqfOkwipsGh4+LNCETFHU5JmZXDTfRhV3V1uQ64Eg=; b=VJk+nbtId17NtzO5keURm+epRRypOl9kgm+iIa6fd57QSopawe0+Se83r39qQqmbKg R/aB13UQUnEh1Z3gkd+jtcjagTWPXwUQEQz+w/pr1R0GSuF6kqelGEh1vACb1rSZ4ZVo 4SYe6N2gbBZEi6hxl3eerVTPaQZiALvcXBtvXMK3BW+++/5HEgyFQaGq7pgoAHz/nVXW IKFhdkcJhO2P+SKlwtDNJYVYZx5GiurkI99qzHafKlSWqO5s3lGkwjZi4mCSUhukPWT3 brtIf3QN0DMU1Q1oEXxNyeDQqa6jPb3nnsP5m/9PxNTFYRLczEzQByVRpxoMy9CBBfNX 1kVg== X-Gm-Message-State: APjAAAWWUKykVxGN2yWj7cVn/M4X865ouyuY6Nz0/mjmmV3Dl/PEWn6g BLI/S66hKoLcnQLFPi0NvKYl9b/0L+8= X-Google-Smtp-Source: APXvYqxLWK60QBB3J4J+3pyoYlKx2r+N57kwxpdy6Xrlh4Da+yQtlaBaJuhTdL6A7bjD/lAmOgP1rQzSEmA= X-Received: by 2002:adf:fe12:: with SMTP id n18mr7384656wrr.114.1571391855100; Fri, 18 Oct 2019 02:44:15 -0700 (PDT) Date: Fri, 18 Oct 2019 11:42:59 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-22-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 21/26] kmsan: unpoison |tlb| in arch_tlb_gather_mmu() From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This is a hack to reduce stackdepot pressure. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I22a201e7e4f67ed74f8129072f12e5351b26103a --- mm/mmu_gather.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c index 7d70e5c78f97..8c5ea2d2e7d5 100644 --- a/mm/mmu_gather.c +++ b/mm/mmu_gather.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -206,6 +207,15 @@ void tlb_flush_mmu(struct mmu_gather *tlb) void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) { + /* + * TODO(glider): struct mmu_gather contains 7 1-bit fields packed into a + * 32-bit unsigned int value. The remaining 25 bits remain uninitialized + * and are never used, but KMSAN updates the origin for them in + * zap_pXX_range() in mm/memory.c, thus creating very long origin + * chains. This is technically correct, but consumes too much memory. + * Unpoisoning the whole structure will prevent creating such chains. + */ + kmsan_unpoison_shadow(tlb, sizeof(*tlb)); tlb->mm = mm; /* Is it from 0 to ~0? */ From patchwork Fri Oct 18 09:43:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11198009 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7005514ED for ; Fri, 18 Oct 2019 09:44:21 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 3C80020820 for ; Fri, 18 Oct 2019 09:44:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="pnKWNJ3d" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3C80020820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id BD86F8E0031; Fri, 18 Oct 2019 05:44:19 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id B881A8E0003; Fri, 18 Oct 2019 05:44:19 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id AC6B28E0031; Fri, 18 Oct 2019 05:44:19 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0162.hostedemail.com [216.40.44.162]) by kanga.kvack.org (Postfix) with ESMTP id 8629C8E0003 for ; Fri, 18 Oct 2019 05:44:19 -0400 (EDT) Received: from smtpin25.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with SMTP id 4190262D9 for ; Fri, 18 Oct 2019 09:44:19 +0000 (UTC) X-FDA: 76056419838.25.dolls05_7cfbeedced532 X-Spam-Summary: 2,0,0,b3a78136f3aba4f0,d41d8cd98f00b204,3compxqykcb8bgd89mbjjbg9.7jhgdips-hhfq57f.jmb@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1535:1543:1593:1594:1711:1730:1747:1777:1792:2393:2559:2562:2895:3138:3139:3140:3141:3142:3152:3354:3867:3868:3870:3871:3874:4321:4605:5007:6120:6261:6653:7901:8603:8660:9969:10004:10400:11026:11232:11473:11657:11658:11914:12043:12296:12297:12438:12555:12895:12986:13148:13230:13846:14096:14097:14181:14394:14659:14721:21080:21365:21444:21451:21611:21627:30054:30064,0,RBL:209.85.222.202:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: dolls05_7cfbeedced532 X-Filterd-Recvd-Size: 5951 Received: from mail-qk1-f202.google.com (mail-qk1-f202.google.com [209.85.222.202]) by imf29.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:18 +0000 (UTC) Received: by mail-qk1-f202.google.com with SMTP id h4so4917255qkd.18 for ; Fri, 18 Oct 2019 02:44:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=hyA1E6SUTuWEQF/SPoSfzqG9ZYu3T7j/J3xG2j/bseI=; b=pnKWNJ3dwof7ofHR3oQwcUok48WGHh1u5DakSH9E870/M9S6Re7Z8zwkUsXlAVG75g vs5HaHw1sq+KsPQ7/ETLatpHEYtfYSMb4XM0H4cCpakO5CLUy36Fnzu4Fqpfuy7VFqQQ ctJq0P93dISH0FxSN7puv5rJ1iK74fwDvPCfBZAIbfmSxCifRn8xwlfikMqt5OlPlLgQ rTrhisPa7QHp5ej5qjUBEW9KdRqSU/7hH4g9rPjJSb24srM3GutgDQ5sZ+2ZKi8VRr8z fibgd4qniGn3A8sqVY26nREN+nd9+h8UmsLOUAR1DKy3vThOI0wNpaRpnw/lfuqzQt6i GeUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=hyA1E6SUTuWEQF/SPoSfzqG9ZYu3T7j/J3xG2j/bseI=; b=SWeE+K1NayZo0HHoPH12Fc1MAudmW5wScx7MV3NjpadY0pLL2kLNEQwbNu4GAjG5BO cokaDu/2wwJ4JiBOZz7wQTSU2nJS3WqIT1d1/3Ye82H6E+61S9vPsp1SHLxvBQPl0hZZ ov7vlcuKufsqqHh9DDDdClYWYc1vRJM5eCwBijimFuoRuzx63FmydbbWrhkiPLvvyEuy DPOOQ7LDO8Hw76D+eyu698Kdok1/lgBSTE7wy3FK/l53chW+ZU+HAg72ZhpMujpm0vW0 H7YWPAkB9ji7h/JdNXZLCvrdfghlZQYnERZosulwjsXQEOjfCBLPM5IRQiZaVpXCdFeX n+zQ== X-Gm-Message-State: APjAAAWymJrP1QR/1CtQWC50rvo74EGULmxFf8JB0z0HBthDukTVyl8U n/xHBYccPXN+hvlQOZIC1WKyS8LSeH8= X-Google-Smtp-Source: APXvYqwbP4TmedWPMkBEEDVbv2lCtzpE424w910Ig7UFcJFsrnTZroMp4G1Qf3g6EyHuhAsabaNC1tlG9Fs= X-Received: by 2002:a0c:fa8a:: with SMTP id o10mr8417746qvn.7.1571391858216; Fri, 18 Oct 2019 02:44:18 -0700 (PDT) Date: Fri, 18 Oct 2019 11:43:00 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-23-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 22/26] kmsan: use __msan_memcpy() where possible. From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Unless stated otherwise (by explicitly calling __memcpy()) we want all memcpy() calls to call __msan_memcpy() so that shadow and origin values are updated accordingly. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: Ib2512ce5aa8d457453dd38caa12f58f002166813 --- arch/x86/include/asm/string_64.h | 9 ++++++++- include/linux/compiler.h | 9 ++++++++- include/linux/string.h | 2 ++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h index 75314c3dbe47..d3c76d910c23 100644 --- a/arch/x86/include/asm/string_64.h +++ b/arch/x86/include/asm/string_64.h @@ -11,7 +11,13 @@ function. */ #define __HAVE_ARCH_MEMCPY 1 +#if defined(CONFIG_KMSAN) +#undef memcpy +/* __msan_memcpy() is defined in compiler.h */ +#define memcpy(dst, src, len) __msan_memcpy(dst, src, len) +#else extern void *memcpy(void *to, const void *from, size_t len); +#endif extern void *__memcpy(void *to, const void *from, size_t len); #define __HAVE_ARCH_MEMSET @@ -64,7 +70,8 @@ char *strcpy(char *dest, const char *src); char *strcat(char *dest, const char *src); int strcmp(const char *cs, const char *ct); -#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) +#if (defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)) || \ + (defined(CONFIG_KMSAN) && !defined(__SANITIZE_MEMORY__)) /* * For files that not instrumented (e.g. mm/slub.c) we diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 4a594bd1bc47..40b1ab13fec7 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -179,6 +179,13 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, #include +#ifdef CONFIG_KMSAN +void *__msan_memcpy(void *dst, const void *src, u64 size); +#define __DO_MEMCPY(res, p, size) __msan_memcpy(res, p, size) +#else +#define __DO_MEMCPY(res, p, size) __builtin_memcpy(res, p, size) +#endif + #define __READ_ONCE_SIZE \ ({ \ switch (size) { \ @@ -188,7 +195,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, case 8: *(__u64 *)res = *(volatile __u64 *)p; break; \ default: \ barrier(); \ - __builtin_memcpy((void *)res, (const void *)p, size); \ + __DO_MEMCPY((void *)res, (const void *)p, size); \ barrier(); \ } \ }) diff --git a/include/linux/string.h b/include/linux/string.h index b6ccdc2c7f02..5d8ce09cba2e 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -363,6 +363,7 @@ __FORTIFY_INLINE void *memset(void *p, int c, __kernel_size_t size) return __builtin_memset(p, c, size); } +#ifndef CONFIG_KMSAN __FORTIFY_INLINE void *memcpy(void *p, const void *q, __kernel_size_t size) { size_t p_size = __builtin_object_size(p, 0); @@ -377,6 +378,7 @@ __FORTIFY_INLINE void *memcpy(void *p, const void *q, __kernel_size_t size) fortify_panic(__func__); return __builtin_memcpy(p, q, size); } +#endif __FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size) { From patchwork Fri Oct 18 09:43:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11198011 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5B2F414ED for ; Fri, 18 Oct 2019 09:44:25 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 0D86520820 for ; Fri, 18 Oct 2019 09:44:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="HYhJafQL" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0D86520820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id B64DE8E0032; Fri, 18 Oct 2019 05:44:23 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id B13198E0003; Fri, 18 Oct 2019 05:44:23 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A01E08E0032; Fri, 18 Oct 2019 05:44:23 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0248.hostedemail.com [216.40.44.248]) by kanga.kvack.org (Postfix) with ESMTP id 783188E0003 for ; Fri, 18 Oct 2019 05:44:23 -0400 (EDT) Received: from smtpin24.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with SMTP id 0CF5D18339497 for ; Fri, 18 Oct 2019 09:44:23 +0000 (UTC) X-FDA: 76056420006.24.fall10_7d7ba2fad084f X-Spam-Summary: 2,0,0,e8412ddb5f7ea80d,d41d8cd98f00b204,3dimpxqykccedifabodlldib.9ljifkru-jjhs79h.lod@flex--glider.bounces.google.com,:glider@google.com:akpm@linux-foundation.org:axboe@kernel.dk:tytso@mit.edu:dmitry.torokhov@gmail.com:martin.petersen@oracle.com:mst@redhat.com:hch@lst.de:edumazet@google.com:ericvh@gmail.com:tiwai@suse.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:4:41:152:355:371:372:379:541:800:960:966:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1593:1594:1605:1730:1747:1777:1792:1981:2194:2196:2198:2199:2200:2201:2393:2559:2562:2640:2693:2731:2898:2899:2904:3138:3139:3140:3141:3142:3152:3865:3866:3867:3868:3870:3871:3872:3874:4250:4321:4385:4605:5007:6119:6120:6261:6653:6742:7514:7901:7903:8603:8957:9036:9969:10004:11026:11232:11473:11658:11914:12043:12291:12296:12297:12438:12555:12679:12895:12986:13846:14096:14097:14394:14659:21060:21080:21324:21365:21433:21444:21451:21611:21627:21740:30003:30012:30045:30054:30064:30070,0,RBL: 209.85.2 X-HE-Tag: fall10_7d7ba2fad084f X-Filterd-Recvd-Size: 17386 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf41.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:22 +0000 (UTC) Received: by mail-wr1-f73.google.com with SMTP id v8so1483043wrt.16 for ; Fri, 18 Oct 2019 02:44:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=pOUwjd35nKVvjlhgx4bOQKBVbyC5r5+P6npeyEw8CAk=; b=HYhJafQL39sNEPe62Nwbvi8F4yhrg/df8kQfWghQlkBFPH3Ot4u7rGBUeup6WJ0xV3 d1sGpfh2xgIotFrmSmgF3lsmXyMWBHdcvu3lUxt4P3+1yXFtHKgoU8CZHzF1hXfjpEs2 bOM9OAAUm0fBgt4dB9jO91UqMCfjCZ6XGmJnZt33QVCVuGzU0DF8GA9oNfdOFWSBb1X0 KqKVvTWyr3t4m9Shxr7soQkgkSRuwvKvCGN0As+J5ytAq81LCWC6DT+qq118ztPSb3lD mbjNFGFrVz85rPGPXRvmQ55I9BTQQWOscdnhDad32GWbELJNVmB23DO8dfbtRfH60fjC 9e1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=pOUwjd35nKVvjlhgx4bOQKBVbyC5r5+P6npeyEw8CAk=; b=skeQTYtzWMAcUTY1eqWsXZXJXcNLg4sRwtRPQ8pl46y05UbyI6rJAYOLfaJoeDSko+ GNDbRIRsvrYKYfEPB+N5ZuxWKgs+tjsd1dLxk90aZzKpAsEnzkR+hlNcckZoF2J+eYTW 11m4fcsY6LL5oR3y0e57lFd9SkxUO9eIXAlfXOArNQzUGGapqcNbexcZzqux65L3rc1j 46Evzwr2grECZpgf+WszVbFkrigS+w0RATCVj0qFBXOUrmw2mJQPstE0TgsO+LA8edvL VCGZ5XMyuX3enqBLHwdIcXz2tPSVu1qxHsKnlsliMwKZAnbKUadjYMkNOVwco62x3VV+ hQZg== X-Gm-Message-State: APjAAAVE4x12eEhjb8Z27yi9Gf+onUxTyQPA89yrj8q9SauR6FlEYKHP 1f5xSZcFB3IsB7pvYrz1FhuKk7btsus= X-Google-Smtp-Source: APXvYqyLa7pFC59EamOyCDumBq0lgnLY7TtX//hXM1PxBd9RSRqFw2Nm7BbctyNlsW0werqlPZvL3yh/sjE= X-Received: by 2002:a5d:51d2:: with SMTP id n18mr6872637wrv.225.1571391860987; Fri, 18 Oct 2019 02:44:20 -0700 (PDT) Date: Fri, 18 Oct 2019 11:43:01 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-24-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 23/26] kmsan: unpoisoning buffers from devices etc. From: glider@google.com To: Alexander Potapenko Cc: Andrew Morton , Jens Axboe , "Theodore Ts'o" , Dmitry Torokhov , "Martin K . Petersen" , "Michael S. Tsirkin" , Christoph Hellwig , Eric Dumazet , Eric Van Hensbergen , Takashi Iwai , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: When data is copied to memory from a device KMSAN should treat it as initialized. In most cases it's enough to just unpoison the buffer that is known to come from a device. In the case with __do_page_cache_readahead() and bio_copy_user_iov() we have to mark the whole pages as ignored by KMSAN, as it's not obvious where these pages are read again. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Andrew Morton Cc: Jens Axboe Cc: "Theodore Ts'o" Cc: Dmitry Torokhov Cc: Martin K. Petersen Cc: "Michael S. Tsirkin" Cc: Christoph Hellwig Cc: Eric Dumazet Cc: Eric Van Hensbergen Cc: Takashi Iwai Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Suggestions on how to avoid scattering too many annotations over the code are welcome. Perhaps annotating DMA reads/writes is enough to get rid of most of these annotations. Change-Id: Id460e7a86ce564f1357469f53d0c7410ca08f0e9 --- block/bio.c | 20 ++++++++++++++++++++ block/partition-generic.c | 9 ++++++++- drivers/char/random.c | 2 ++ drivers/input/serio/libps2.c | 6 +++++- drivers/scsi/scsi_lib.c | 4 ++++ drivers/usb/core/message.c | 6 +++++- drivers/virtio/virtio_ring.c | 14 ++++++++++++++ fs/buffer.c | 7 ++++++- include/linux/dma-mapping.h | 2 ++ include/linux/skbuff.h | 5 ++++- mm/filemap.c | 3 +++ mm/readahead.c | 6 ++++++ net/9p/protocol.c | 2 ++ sound/core/oss/pcm_oss.c | 7 +++++++ 14 files changed, 88 insertions(+), 5 deletions(-) diff --git a/block/bio.c b/block/bio.c index 8f0ed6228fc5..40773cf4b50c 100644 --- a/block/bio.c +++ b/block/bio.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -900,6 +901,13 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) __bio_add_page(bio, page, len, offset); } offset = 0; + /* + * TODO(glider): these pages will be soon passed to block + * device for reading, so consider them initialized. + */ + if (iov_iter_rw(iter) == READ) + kmsan_unpoison_shadow(page_address(page), + PAGE_SIZE); } iov_iter_advance(iter, size); @@ -1274,11 +1282,16 @@ struct bio *bio_copy_user_iov(struct request_queue *q, i++; } else { + /* + * TODO(glider): KMSAN doesn't track the pages + * allocated for bio here. + */ page = alloc_page(q->bounce_gfp | gfp_mask); if (!page) { ret = -ENOMEM; break; } + kmsan_ignore_page(page, /*order*/0); } if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) { @@ -1574,6 +1587,13 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len, if (!page) goto cleanup; + /* + * TODO(glider): if we're about to read data from a SCSI device, + * assume the page allocated for that is already initialized. + */ + if (reading) + kmsan_unpoison_shadow(page_address(page), PAGE_SIZE); + if (!reading) memcpy(page_address(page), p, bytes); diff --git a/block/partition-generic.c b/block/partition-generic.c index aee643ce13d1..87b3ae9e7727 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -663,13 +663,20 @@ unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) { struct address_space *mapping = bdev->bd_inode->i_mapping; struct page *page; + unsigned char *retval; page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_SHIFT-9)), NULL); if (!IS_ERR(page)) { if (PageError(page)) goto fail; p->v = page; - return (unsigned char *)page_address(page) + ((n & ((1 << (PAGE_SHIFT - 9)) - 1)) << 9); + retval = (unsigned char *)page_address(page) + + ((n & ((1 << (PAGE_SHIFT - 9)) - 1)) << 9); + /* + * Unpoison sector-sized chunk of memory coming from the device. + */ + kmsan_unpoison_shadow(retval, SECTOR_SIZE); + return retval; fail: put_page(page); } diff --git a/drivers/char/random.c b/drivers/char/random.c index de434feb873a..cc4afc0f1039 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -320,6 +320,7 @@ #include #include #include +#include #include #include #include @@ -1061,6 +1062,7 @@ static void _extract_crng(struct crng_state *crng, spin_lock_irqsave(&crng->lock, flags); if (arch_get_random_long(&v)) crng->state[14] ^= v; + kmsan_unpoison_shadow(crng->state, sizeof(crng->state)); chacha20_block(&crng->state[0], out); if (crng->state[12] == 0) crng->state[13]++; diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index a8c94a940a79..80a9e0a9d3c3 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -30,6 +31,7 @@ static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte, int error; lockdep_assert_held(&ps2dev->serio->lock); + kmsan_check_memory(&byte, 1); do { ps2dev->nak = 1; @@ -294,9 +296,11 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) serio_pause_rx(ps2dev->serio); - if (param) + if (param) { for (i = 0; i < receive; i++) param[i] = ps2dev->cmdbuf[(receive - 1) - i]; + kmsan_unpoison_shadow(param, receive); + } if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) { diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index dc210b9d4896..4235b317ac5f 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -296,6 +297,9 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, ret = rq->result; out: blk_put_request(req); + /* TODO(glider): this is a bit rough. */ + if (data_direction == DMA_FROM_DEVICE) + kmsan_unpoison_shadow(buffer, bufflen); return ret; } diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 5adf489428aa..f1c3f8b3cfae 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -101,8 +102,11 @@ static int usb_internal_control_msg(struct usb_device *usb_dev, retv = usb_start_wait_urb(urb, timeout, &length); if (retv < 0) return retv; - else + else { + /* TODO(glider): USB initializes |length| bytes? */ + kmsan_unpoison_shadow(data, length); return length; + } } /** diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index bdc08244a648..8b7ddc43618f 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #ifdef DEBUG @@ -387,6 +388,12 @@ static void vring_unmap_one_split(const struct vring_virtqueue *vq, (flags & VRING_DESC_F_WRITE) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } + /* + * Unmapping DMA memory after a transfer from device requires this + * memory to be unpoisoned. + */ + if (flags & VRING_DESC_F_WRITE) + kmsan_unpoison_shadow((const void *)desc->addr, desc->len); } static struct vring_desc *alloc_indirect_split(struct virtqueue *_vq, @@ -500,6 +507,13 @@ static inline int virtqueue_add_split(struct virtqueue *_vq, desc[i].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_NEXT | VRING_DESC_F_WRITE); desc[i].addr = cpu_to_virtio64(_vq->vdev, addr); desc[i].len = cpu_to_virtio32(_vq->vdev, sg->length); + /* + * It's hard to figure out the buffer's address upon + * receive. Instead we unpoison it once, when exposing + * it to the device, and hope nobody else will write to + * it. + */ + kmsan_unpoison_shadow(sg_virt(sg), sg->length); prev = i; i = virtio16_to_cpu(_vq->vdev, desc[i].next); } diff --git a/fs/buffer.c b/fs/buffer.c index 86a38b979323..c08fb1a77fa1 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1170,14 +1170,17 @@ static struct buffer_head *__bread_slow(struct buffer_head *bh) lock_buffer(bh); if (buffer_uptodate(bh)) { unlock_buffer(bh); + kmsan_unpoison_shadow(bh->b_data, bh->b_size); return bh; } else { get_bh(bh); bh->b_end_io = end_buffer_read_sync; submit_bh(REQ_OP_READ, 0, bh); wait_on_buffer(bh); - if (buffer_uptodate(bh)) + if (buffer_uptodate(bh)) { + kmsan_unpoison_shadow(bh->b_data, bh->b_size); return bh; + } } brelse(bh); return NULL; @@ -1320,6 +1323,8 @@ __getblk_gfp(struct block_device *bdev, sector_t block, might_sleep(); if (bh == NULL) bh = __getblk_slow(bdev, block, size, gfp); + if (bh) + kmsan_unpoison_shadow(bh->b_data, bh->b_size); return bh; } EXPORT_SYMBOL(__getblk_gfp); diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 4a1c4fca475a..cc7b05eb024f 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -281,6 +282,7 @@ static inline dma_addr_t dma_map_page_attrs(struct device *dev, const struct dma_map_ops *ops = get_dma_ops(dev); dma_addr_t addr; + kmsan_unpoison_shadow(page_address(page), size); BUG_ON(!valid_dma_direction(dir)); if (dma_is_direct(ops)) addr = dma_direct_map_page(dev, page, offset, size, dir, attrs); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4351577b14d7..b8e9cd697248 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -11,6 +11,7 @@ #define _LINUX_SKBUFF_H #include +#include #include #include #include @@ -2214,6 +2215,8 @@ static inline void *skb_put_data(struct sk_buff *skb, const void *data, { void *tmp = skb_put(skb, len); + /* Unpoison the data received from the network device. */ + kmsan_unpoison_shadow(data, len); memcpy(tmp, data, len); return tmp; @@ -2221,7 +2224,7 @@ static inline void *skb_put_data(struct sk_buff *skb, const void *data, static inline void skb_put_u8(struct sk_buff *skb, u8 val) { - *(u8 *)skb_put(skb, 1) = val; + *(u8 *)skb_put(skb, 1) = KMSAN_INIT_VALUE(val); } void *skb_push(struct sk_buff *skb, unsigned int len); diff --git a/mm/filemap.c b/mm/filemap.c index 1146fcfa3215..8a17f15806cc 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -2810,6 +2811,8 @@ static struct page *do_read_cache_page(struct address_space *mapping, page = wait_on_page_read(page); if (IS_ERR(page)) return page; + /* Assume all pages in page cache are initialized. */ + kmsan_unpoison_shadow(page_address(page), PAGE_SIZE); goto out; } if (PageUptodate(page)) diff --git a/mm/readahead.c b/mm/readahead.c index 2fe72cd29b47..1fe61128095b 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -193,7 +193,13 @@ unsigned int __do_page_cache_readahead(struct address_space *mapping, continue; } + /* + * The easiest way to handle these pages is to mark them + * untracked by KMSAN, assuming they're never used by anything + * else. + */ page = __page_cache_alloc(gfp_mask); + kmsan_ignore_page(page, /*order*/0); if (!page) break; page->index = page_offset; diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 03593eb240d8..5d88ed181422 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ EXPORT_SYMBOL(p9stat_free); size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size) { size_t len = min(pdu->size - pdu->offset, size); + kmsan_unpoison_shadow(&pdu->sdata[pdu->offset], len); memcpy(data, &pdu->sdata[pdu->offset], len); pdu->offset += len; return size - len; diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index f57c610d7523..c3795e495196 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -12,6 +12,7 @@ #endif #include +#include /* for kmsan_unpoison_shadow() */ #include #include #include @@ -1054,6 +1055,12 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) err = -ENOMEM; goto failure; } + /* + * Unpoison the freshly created buffer to prevent KMSAN from reporting + * uninit errors. + * TODO(glider): unpoison it only when it's actually initialized. + */ + kmsan_unpoison_shadow(runtime->oss.buffer, runtime->oss.period_bytes); runtime->oss.params = 0; runtime->oss.prepare = 1; From patchwork Fri Oct 18 09:43:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11198013 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6442413B1 for ; Fri, 18 Oct 2019 09:44:28 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 22CCD20820 for ; Fri, 18 Oct 2019 09:44:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ONUsvDR+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 22CCD20820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id A59EC8E0033; Fri, 18 Oct 2019 05:44:26 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id A06598E0003; Fri, 18 Oct 2019 05:44:26 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 82CD88E0033; Fri, 18 Oct 2019 05:44:26 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0127.hostedemail.com [216.40.44.127]) by kanga.kvack.org (Postfix) with ESMTP id 5EAB28E0003 for ; Fri, 18 Oct 2019 05:44:26 -0400 (EDT) Received: from smtpin21.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id 0B6B24DD3 for ; Fri, 18 Oct 2019 09:44:26 +0000 (UTC) X-FDA: 76056420132.21.scarf28_7dec27dad0836 X-Spam-Summary: 2,0,0,350bc1221d89f8c8,d41d8cd98f00b204,3d4mpxqykccqglidergoogle.comlinux-mmkvack.org@flex--glider.bounces.google.com,:glider@google.com:viro@zeniv.linux.org.uk:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:1:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1593:1594:1605:1730:1747:1777:1792:1981:2194:2199:2393:2559:2562:2636:3138:3139:3140:3141:3142:3152:3865:3867:3868:3871:3872:3874:4321:4605:5007:6120:6261:6653:7901:8603:9969:10004:11026:11232:11473:11657:11658:11914:12043:12291:12296:12297:12438:12555:12683:12895:12986:13846:14096:14097:14394:14659:21080:21365:21444:21451:21627:30051:30054:30064:30070,0,RBL:209.85.128.74:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: scarf28_7dec27dad0836 X-Filterd-Recvd-Size: 12911 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf06.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:25 +0000 (UTC) Received: by mail-wm1-f74.google.com with SMTP id k9so2459339wmb.0 for ; Fri, 18 Oct 2019 02:44:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=0LBnpJ/PZi/hKcWlUiJTdcWDbSBugSGoVDupLMRQ2dM=; b=ONUsvDR+8ebqCKsgN/4O7ETZrVMhGLdGCLYb+pZDB3DSaHtEZzO8WOiL18lzysTSRA dXSLoFedM8QBfXxq8z9L06TD/yfBYjvOS5sSkt0pR9y1BlYn7fHwtGoQ/jhFRu+6tllQ Zq3P1vIvXz5zMK+9SECiLMEJzdbutqKROTQw4K3vi15msQn0522QkkTgK+lmenZ+6pnL H5s4hbzqfHn3WGif3XpUD2wFt7JKIfmKb4luaArErLsOd3syyym1axlfYTAktDssiOBj qqLMOxMl63Hd9TpCq24IpbvNb/xqG54T9sKPEvrbyonypL43S+XRgSW3t6KIQ0hoaO6T YtFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=0LBnpJ/PZi/hKcWlUiJTdcWDbSBugSGoVDupLMRQ2dM=; b=jV4m1o02XOzSb/uwFaynldV/IBQMgIHYDnnKwzrfPYnudVZ0Cj+2EEXReWCePPNe1M ZVPpt53Q9mz5hvPsoAXfOq+N6UB32xw9QciBb8Q4h4jGV7mla9ERjVe1RbYZlngs3CWK DNz46h+iIxieTpaa9mz/HdIHNjy2zOQKVQD3WNdhS2r14g4x3VFDDq3o3t3s0si2OvkJ C4zu45RU88WYHNo8aaray4UFjpfq7aZ0v72XCkGWZKsJdQ84GcXFPKPyt3ZhCoCGj5mH JCWBVqHBAO4F1R+bxo3nOQn7PnKMC2dOq9tfJJXkpNCG1mqvi+B+cMdfofMxR9C7W6XB hTSw== X-Gm-Message-State: APjAAAXBn9vvF0hjaFeZ8r0vLVuEW9qw+98bkgckqt7rm3IyJx5pCbXI HZCjtqioqBRboSKcqK9H4rHG7Yce1pY= X-Google-Smtp-Source: APXvYqwMC+eEiyPvJCuo9KwprjIqTxSDn8kNF8ECjJjxff8A2GPUWfQV6zNSefwIsZKQIZzdiXjHBIduAmg= X-Received: by 2002:a5d:638b:: with SMTP id p11mr6547328wru.372.1571391863896; Fri, 18 Oct 2019 02:44:23 -0700 (PDT) Date: Fri, 18 Oct 2019 11:43:02 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-25-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 24/26] kmsan: hooks for copy_to_user() and friends From: glider@google.com To: Alexander Potapenko Cc: Alexander Viro , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Memory that is copied from userspace must be unpoisoned. Before copying memory to userspace, check it and report an error if it contains uninitialized bits. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Alexander Viro Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I38428b9c7d1909b8441dcec1749b080494a7af99 --- arch/x86/include/asm/uaccess.h | 12 ++++++++++++ include/asm-generic/cacheflush.h | 7 ++++++- include/asm-generic/uaccess.h | 12 ++++++++++-- include/linux/uaccess.h | 32 +++++++++++++++++++++++++++----- lib/iov_iter.c | 6 ++++++ lib/usercopy.c | 6 +++++- 6 files changed, 66 insertions(+), 9 deletions(-) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 61d93f062a36..ac4b26583f7c 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -6,6 +6,7 @@ */ #include #include +#include #include #include #include @@ -174,6 +175,7 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) ASM_CALL_CONSTRAINT \ : "0" (ptr), "i" (sizeof(*(ptr)))); \ (x) = (__force __typeof__(*(ptr))) __val_gu; \ + kmsan_unpoison_shadow(&(x), sizeof(*(ptr))); \ __builtin_expect(__ret_gu, 0); \ }) @@ -248,6 +250,7 @@ extern void __put_user_8(void); __chk_user_ptr(ptr); \ might_fault(); \ __pu_val = x; \ + kmsan_check_memory(&(__pu_val), sizeof(*(ptr))); \ switch (sizeof(*(ptr))) { \ case 1: \ __put_user_x(1, __pu_val, ptr, __ret_pu); \ @@ -270,7 +273,9 @@ extern void __put_user_8(void); #define __put_user_size(x, ptr, size, label) \ do { \ + __typeof__(*(ptr)) __pus_val = x; \ __chk_user_ptr(ptr); \ + kmsan_check_memory(&(__pus_val), size); \ switch (size) { \ case 1: \ __put_user_goto(x, ptr, "b", "b", "iq", label); \ @@ -295,7 +300,10 @@ do { \ */ #define __put_user_size_ex(x, ptr, size) \ do { \ + __typeof__(*(ptr)) __puse_val; \ __chk_user_ptr(ptr); \ + __puse_val = x; \ + kmsan_check_memory(&(__puse_val), size); \ switch (size) { \ case 1: \ __put_user_asm_ex(x, ptr, "b", "b", "iq"); \ @@ -363,6 +371,7 @@ do { \ default: \ (x) = __get_user_bad(); \ } \ + kmsan_unpoison_shadow(&(x), size); \ } while (0) #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \ @@ -413,6 +422,7 @@ do { \ default: \ (x) = __get_user_bad(); \ } \ + kmsan_unpoison_shadow(&(x), size); \ } while (0) #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ @@ -428,11 +438,13 @@ do { \ #define __put_user_nocheck(x, ptr, size) \ ({ \ __label__ __pu_label; \ + __typeof__(*(ptr)) __pun_val = x; \ int __pu_err = -EFAULT; \ __typeof__(*(ptr)) __pu_val = (x); \ __typeof__(ptr) __pu_ptr = (ptr); \ __typeof__(size) __pu_size = (size); \ __uaccess_begin(); \ + kmsan_check_memory(&(__pun_val), size); \ __put_user_size(__pu_val, __pu_ptr, __pu_size, __pu_label); \ __pu_err = 0; \ __pu_label: \ diff --git a/include/asm-generic/cacheflush.h b/include/asm-generic/cacheflush.h index a950a22c4890..707531dccf5e 100644 --- a/include/asm-generic/cacheflush.h +++ b/include/asm-generic/cacheflush.h @@ -4,6 +4,7 @@ /* Keep includes the same across arches. */ #include +#include #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 @@ -72,10 +73,14 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ + kmsan_check_memory(src, len); \ memcpy(dst, src, len); \ flush_icache_user_range(vma, page, vaddr, len); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ - memcpy(dst, src, len) + do { \ + memcpy(dst, src, len); \ + kmsan_unpoison_shadow(dst, len); \ + } while (0) #endif /* __ASM_CACHEFLUSH_H */ diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h index e935318804f8..18a50333ffc0 100644 --- a/include/asm-generic/uaccess.h +++ b/include/asm-generic/uaccess.h @@ -142,7 +142,11 @@ static inline int __access_ok(unsigned long addr, unsigned long size) static inline int __put_user_fn(size_t size, void __user *ptr, void *x) { - return unlikely(raw_copy_to_user(ptr, x, size)) ? -EFAULT : 0; + int n; + + n = raw_copy_to_user(ptr, x, size); + kmsan_copy_to_user(ptr, x, size, n); + return unlikely(n) ? -EFAULT : 0; } #define __put_user_fn(sz, u, k) __put_user_fn(sz, u, k) @@ -203,7 +207,11 @@ extern int __put_user_bad(void) __attribute__((noreturn)); #ifndef __get_user_fn static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) { - return unlikely(raw_copy_from_user(x, ptr, size)) ? -EFAULT : 0; + int copied, to_copy = size; + + copied = raw_copy_from_user(x, ptr, size); + kmsan_unpoison_shadow(to, to_copy - res); + return unlikely(copied) ? -EFAULT : 0; } #define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k) diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index d4ee6e942562..4257b5f80689 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -5,6 +5,7 @@ #include #include #include +#include #define uaccess_kernel() segment_eq(get_fs(), KERNEL_DS) @@ -58,18 +59,26 @@ static __always_inline __must_check unsigned long __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) { + unsigned long to_copy = n; + kasan_check_write(to, n); check_object_size(to, n, false); - return raw_copy_from_user(to, from, n); + n = raw_copy_from_user(to, from, n); + kmsan_unpoison_shadow(to, to_copy - n); + return n; } static __always_inline __must_check unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) { + unsigned long to_copy = n; + might_fault(); kasan_check_write(to, n); check_object_size(to, n, false); - return raw_copy_from_user(to, from, n); + n = raw_copy_from_user(to, from, n); + kmsan_unpoison_shadow(to, to_copy - n); + return n; } /** @@ -88,29 +97,39 @@ __copy_from_user(void *to, const void __user *from, unsigned long n) static __always_inline __must_check unsigned long __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) { + unsigned long to_copy = n; + kasan_check_read(from, n); check_object_size(from, n, true); - return raw_copy_to_user(to, from, n); + n = raw_copy_to_user(to, from, n); + kmsan_copy_to_user(to, from, to_copy, n); + return n; } static __always_inline __must_check unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) { + unsigned long to_copy = n; + might_fault(); kasan_check_read(from, n); check_object_size(from, n, true); - return raw_copy_to_user(to, from, n); + n = raw_copy_to_user(to, from, n); + kmsan_copy_to_user(to, from, to_copy, n); + return n; } #ifdef INLINE_COPY_FROM_USER static inline __must_check unsigned long _copy_from_user(void *to, const void __user *from, unsigned long n) { - unsigned long res = n; + unsigned long res = n, to_copy = n; + might_fault(); if (likely(access_ok(from, n))) { kasan_check_write(to, n); res = raw_copy_from_user(to, from, n); + kmsan_unpoison_shadow(to, to_copy - res); } if (unlikely(res)) memset(to + (n - res), 0, res); @@ -125,10 +144,13 @@ _copy_from_user(void *, const void __user *, unsigned long); static inline __must_check unsigned long _copy_to_user(void __user *to, const void *from, unsigned long n) { + unsigned long to_copy = n; + might_fault(); if (access_ok(to, n)) { kasan_check_read(from, n); n = raw_copy_to_user(to, from, n); + kmsan_copy_to_user(to, from, to_copy, n); } return n; } diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 639d5e7014c1..f038676068b2 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -137,18 +137,24 @@ static int copyout(void __user *to, const void *from, size_t n) { + size_t to_copy = n; + if (access_ok(to, n)) { kasan_check_read(from, n); n = raw_copy_to_user(to, from, n); + kmsan_copy_to_user(to, from, to_copy, n); } return n; } static int copyin(void *to, const void __user *from, size_t n) { + size_t to_copy = n; + if (access_ok(from, n)) { kasan_check_write(to, n); n = raw_copy_from_user(to, from, n); + kmsan_unpoison_shadow(to, to_copy - n); } return n; } diff --git a/lib/usercopy.c b/lib/usercopy.c index cbb4d9ec00f2..abfd93edecba 100644 --- a/lib/usercopy.c +++ b/lib/usercopy.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include @@ -7,11 +8,12 @@ #ifndef INLINE_COPY_FROM_USER unsigned long _copy_from_user(void *to, const void __user *from, unsigned long n) { - unsigned long res = n; + unsigned long res = n, to_copy = n; might_fault(); if (likely(access_ok(from, n))) { kasan_check_write(to, n); res = raw_copy_from_user(to, from, n); + kmsan_unpoison_shadow(to, to_copy - res); } if (unlikely(res)) memset(to + (n - res), 0, res); @@ -23,10 +25,12 @@ EXPORT_SYMBOL(_copy_from_user); #ifndef INLINE_COPY_TO_USER unsigned long _copy_to_user(void __user *to, const void *from, unsigned long n) { + unsigned long to_copy = n; might_fault(); if (likely(access_ok(to, n))) { kasan_check_read(from, n); n = raw_copy_to_user(to, from, n); + kmsan_copy_to_user(to, from, to_copy, n); } return n; } From patchwork Fri Oct 18 09:43:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11198015 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D6A0413B1 for ; Fri, 18 Oct 2019 09:44:30 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id A40DF21D7C for ; Fri, 18 Oct 2019 09:44:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="kgdMpbU6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A40DF21D7C Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 304908E0034; Fri, 18 Oct 2019 05:44:29 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 211F78E0003; Fri, 18 Oct 2019 05:44:29 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 100CA8E0034; Fri, 18 Oct 2019 05:44:29 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0244.hostedemail.com [216.40.44.244]) by kanga.kvack.org (Postfix) with ESMTP id E0A7E8E0003 for ; Fri, 18 Oct 2019 05:44:28 -0400 (EDT) Received: from smtpin17.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with SMTP id 93DD6F038 for ; Fri, 18 Oct 2019 09:44:28 +0000 (UTC) X-FDA: 76056420216.17.goat81_7e5643069f748 X-Spam-Summary: 2,0,0,0225610fac23fc1f,d41d8cd98f00b204,3e4mpxqykccgkpmhivksskpi.gsqpmryb-qqozego.svk@flex--glider.bounces.google.com,:glider@google.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1437:1516:1518:1534:1541:1593:1594:1711:1730:1747:1777:1792:2393:2559:2562:3138:3139:3140:3141:3142:3152:3352:3865:3867:3871:4250:4321:5007:6119:6120:6261:6653:7901:7903:9969:10004:10400:11026:11232:11473:11658:11914:12043:12297:12438:12555:12895:12986:13069:13311:13357:13846:14096:14097:14181:14394:14659:14721:21080:21365:21444:21451:21627:30054:30064,0,RBL:209.85.221.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.175.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:3,LUA_SUMMARY:none X-HE-Tag: goat81_7e5643069f748 X-Filterd-Recvd-Size: 3675 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf50.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:28 +0000 (UTC) Received: by mail-wr1-f73.google.com with SMTP id w10so2350613wrl.5 for ; Fri, 18 Oct 2019 02:44:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=F+SkbUx7nCBevvRWhTjoMhc2XnLN3BBIN0tYS79pL9c=; b=kgdMpbU6UkL66TSoKyO6wRkyK5rV/1HIjD2Y1RzThUPOGp0ocujomKDNiciZkWHowW txrDOr0SWTniBEUHJX4X6vr49oaUypnmvIjtjlLshNbWDwl/JRordYpMYcqsVzELhUgM 1Fk/l348/QT0GaNFehouWSgw4bvlh/kDqgZxgIKvfke+ol27NNX1LbdgaO0z9L5M9n/d Ti8xoFA+BuecACq4ySwHMF5yH0nkXvvb+Et2vzHRy7Ed9eqEe9JOMIodg+pYhuHGRgoZ +HPD7uoHqDLCsSkXv7y0EsBg8OMml7FFst2fPYF1TO5pN86Ynw81qR7I615PzjD4BCER DM7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=F+SkbUx7nCBevvRWhTjoMhc2XnLN3BBIN0tYS79pL9c=; b=tITeQY0aM254HZkxxi1qcGIL8vk58r5xp4konlxFFZlvhaRaKW+YZ42U9R1UCYiow2 YYRY2vgNSgeRTXed9rpvFb9aWOx1nu3Jzaso+UcOLGMrMnDtO2CaZJ9t+KfarHN0KXih 3inFf9lu/gF6p3Y3ExZ7S2eXRuxu30W8wEr7ZoQzb5MT23K6ANPC6CRL/Fkvo/Zh993E 8fooNAgImFULleVBTe+im6EsXS2FQ5K0TBkppDevgg6driKKXQYsqelRdAVY2GYFa0qU 5XP9C+I4TlSx6FCEmFuSZCK4Sm69+GtlcnSbOAp07/9xzMCQnmZcj7v71qhijLnicm9H 7WTw== X-Gm-Message-State: APjAAAVXZ9crK2p2jhmbxvEQmBIZmhZpvV50ieNK5nqBx/RN8E8zLVSz Rz6IN7QfIDboAXeX4Fo7aJ3vM4ktJgo= X-Google-Smtp-Source: APXvYqyno7X3jieZVENfBEF0UAiT9r743xvUKsC9BRYVTTd2aDsMQ1xryKmZeYz/iTduQT7f+CROGw1RPqA= X-Received: by 2002:a5d:5011:: with SMTP id e17mr6998931wrt.160.1571391867014; Fri, 18 Oct 2019 02:44:27 -0700 (PDT) Date: Fri, 18 Oct 2019 11:43:03 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-26-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 25/26] kmsan: disable strscpy() optimization under KMSAN From: glider@google.com To: Alexander Potapenko Cc: Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Disable the efficient 8-byte reading under KMSAN to avoid false positives. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I25d1acf5c3df6eff85894cd94f5ddbe93308271c --- lib/string.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/string.c b/lib/string.c index 08ec58cc673b..15efdc51bda6 100644 --- a/lib/string.c +++ b/lib/string.c @@ -186,7 +186,10 @@ ssize_t strscpy(char *dest, const char *src, size_t count) if (count == 0 || WARN_ON_ONCE(count > INT_MAX)) return -E2BIG; -#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS +/** + * Disable the efficient 8-byte reading under KMSAN to avoid false positives. + */ +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && !defined(CONFIG_KMSAN) /* * If src is unaligned, don't cross a page boundary, * since we don't know if the next page is mapped. From patchwork Fri Oct 18 09:43:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 11198017 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A16FC18A6 for ; Fri, 18 Oct 2019 09:44:33 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 6E97F20820 for ; Fri, 18 Oct 2019 09:44:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AT8VyP2L" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6E97F20820 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 5E4AD8E0035; Fri, 18 Oct 2019 05:44:32 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 56E3F8E0003; Fri, 18 Oct 2019 05:44:32 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 483A98E0035; Fri, 18 Oct 2019 05:44:32 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0097.hostedemail.com [216.40.44.97]) by kanga.kvack.org (Postfix) with ESMTP id 27E298E0003 for ; Fri, 18 Oct 2019 05:44:32 -0400 (EDT) Received: from smtpin15.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with SMTP id A3EDB182EE036 for ; Fri, 18 Oct 2019 09:44:31 +0000 (UTC) X-FDA: 76056420342.15.slope79_7ec7165eab361 X-Spam-Summary: 2,0,0,6f9d9f0aade35f99,d41d8cd98f00b204,3fympxqykccomrojkxmuumrk.iusrotad-ssqbgiq.uxm@flex--glider.bounces.google.com,:glider@google.com:arnd@arndb.de:monstr@monstr.eu:aryabinin@virtuozzo.com:vegard.nossum@oracle.com:dvyukov@google.com:,RULES_HIT:41:152:355:379:541:800:960:973:988:989:1260:1277:1313:1314:1345:1359:1431:1437:1516:1518:1535:1542:1593:1594:1711:1730:1747:1777:1792:1981:2194:2199:2393:2559:2562:3138:3139:3140:3141:3142:3152:3353:3865:3866:3867:3868:3871:3872:4250:4321:4605:5007:6120:6261:6653:7901:7904:9121:9969:10004:10400:10471:11026:11232:11473:11657:11658:11914:12043:12296:12297:12438:12555:12895:13255:13846:14096:14097:14181:14394:14659:14721:21080:21365:21444:21451:21627:30012:30041:30054:30064,0,RBL:209.85.128.73:@flex--glider.bounces.google.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: slope79_7ec7165eab361 X-Filterd-Recvd-Size: 5173 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf49.hostedemail.com (Postfix) with ESMTP for ; Fri, 18 Oct 2019 09:44:31 +0000 (UTC) Received: by mail-wm1-f73.google.com with SMTP id 190so2453740wme.4 for ; Fri, 18 Oct 2019 02:44:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=MkrF0HFNZAmyt7YYXlDmiKQfJmn/DaWkPMYO97xCgaA=; b=AT8VyP2LiGwEKKeTKzmePGCkI7jdHxb8U2ZSXK79iKApxMPNTKXR9F5cnT7alnjURJ tByJjO34qgJ80o1DBQ6A7Zut4i9tn6SCesKX3lToN10rXaoRKrD2QR+WIzDbzzjnnlt7 o4XMHI1LmUP3lH03lUN218oWwt6NwgNnLw8pP2MLd19QT71k1uNsohCokZ3T7uB0hXe3 yIPIcPfXTd+N6kY/74+fs2nEabXbNxkQHBdeQwaekdd74MYf9pdlGomztq0aIeLAQjP+ TabeKDwLn+rGuIbcdwE9f24Hvu+nE0/rUC3IvzHLgy98Tfm7cnHpEOtpVRe2nwkBPzf8 1Wcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=MkrF0HFNZAmyt7YYXlDmiKQfJmn/DaWkPMYO97xCgaA=; b=bdlR/NduASZBvW3Y2C+/Xh6AoSs9CMPtNk14ANuJw0WeB3COrko1SkRDCnHJRt0pZB ztEnYLMoZuBfOvTo/rOlrHlyGQCcs1hxvi0nRUs75qNzeTMLPlb6lBs+wfs622xas8ov 2r5LXUOsyHVsIqmHdEn2X1eNbliV0aMAJHZn+HvhJD4YPH6OH393bQZYC0I5xKB03BUK 3uqA2jCgWaqbLA23Qvv8LZj5ef6mha6fehxlI2T70w67Oq058t1J82spRW43q9Th7AYo SutP2SJNJNE2CC8UwX7Hzj6jXuQU4AIbgM8x/4kxBf7yKLv2N80iTDZVvmWDYz8CiWwq XgIA== X-Gm-Message-State: APjAAAWamQM8p9P5UCIIFfYi8WbABF64qWI6DHR3EJWsXR5cAiaulkvc NYMyRd/vb/mym9HWfTu6OAIjObTIYIU= X-Google-Smtp-Source: APXvYqzg1MOpLicaE0X+Iw5SmEmA896FkE9605iQtLcLLtCsJwBRPFctKJzyF33pWAKrgM01Ushu7Hr3KQU= X-Received: by 2002:adf:e5c4:: with SMTP id a4mr7205413wrn.334.1571391869987; Fri, 18 Oct 2019 02:44:29 -0700 (PDT) Date: Fri, 18 Oct 2019 11:43:04 +0200 In-Reply-To: <20191018094304.37056-1-glider@google.com> Message-Id: <20191018094304.37056-27-glider@google.com> Mime-Version: 1.0 References: <20191018094304.37056-1-glider@google.com> X-Mailer: git-send-email 2.23.0.866.gb869b98d4c-goog Subject: [PATCH RFC v1 26/26] net: kasan: kmsan: support CONFIG_GENERIC_CSUM on x86, enable it for KASAN/KMSAN From: glider@google.com To: Alexander Potapenko Cc: Arnd Bergmann , Michal Simek , Andrey Ryabinin , Vegard Nossum , Dmitry Vyukov , linux-mm@kvack.org X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This is needed to allow memory tools like KASAN and KMSAN see the memory accesses from the checksum code. Without CONFIG_GENERIC_CSUM the tools can't see memory accesses originating from handwritten assembly code. For KASAN it's a question of detecting more bugs, for KMSAN using the C implementation also helps avoid false positives originating from seemingly uninitialized checksum values. Signed-off-by: Alexander Potapenko To: Alexander Potapenko Cc: Arnd Bergmann Cc: Michal Simek Cc: Andrey Ryabinin Cc: Vegard Nossum Cc: Dmitry Vyukov Cc: linux-mm@kvack.org --- Change-Id: I645e2c097253a8d5717ad87e2e2df6f6f67251f3 --- arch/x86/Kconfig | 5 +++++ arch/x86/include/asm/checksum.h | 10 +++++++--- arch/x86/lib/Makefile | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6d2b0fb3a871..dfec655d1a7a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -272,6 +272,11 @@ config GENERIC_ISA_DMA def_bool y depends on ISA_DMA_API +config GENERIC_CSUM + bool + default y if KMSAN || KASAN + default n + config GENERIC_BUG def_bool y depends on BUG diff --git a/arch/x86/include/asm/checksum.h b/arch/x86/include/asm/checksum.h index d79d1e622dcf..ab3464cbce26 100644 --- a/arch/x86/include/asm/checksum.h +++ b/arch/x86/include/asm/checksum.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifdef CONFIG_X86_32 -# include +#ifdef CONFIG_GENERIC_CSUM +# include #else -# include +# ifdef CONFIG_X86_32 +# include +# else +# include +# endif #endif diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 5246db42de45..bca9031de9ff 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -55,7 +55,9 @@ endif lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o else obj-y += iomap_copy_64.o +ifneq ($(CONFIG_GENERIC_CSUM),y) lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o +endif lib-y += clear_page_64.o copy_page_64.o lib-y += memmove_64.o memset_64.o lib-y += copy_user_64.o