Received: by 2002:a25:f815:0:0:0:0:0 with SMTP id u21csp743350ybd; Wed, 26 Jun 2019 05:25:58 -0700 (PDT) X-Google-Smtp-Source: APXvYqzhgp1QTQ8guY0NB6oTHdlTabpooocvMDve1KkWQQ2cuT1xc5mFrPvzHRIy0kfy5suYix8t X-Received: by 2002:a63:6143:: with SMTP id v64mr2660174pgb.407.1561551958732; Wed, 26 Jun 2019 05:25:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561551958; cv=none; d=google.com; s=arc-20160816; b=VVIAsEDxLGecAm7Zfx8LLzIAjtDnwH8hxO942qRr6gFtSTTVAJ/rf7XBpWW3srM6wq 0Dns+BijEd/sa15jEaRzQVryWH/F6Tpl9Dir1Lll0i64giCWGw16cupXkMIL6GshxS1V YV+0+OzU9AXzzw2EiqouXQWH+BRB2FT258eEpfy6XFByRXXpNIaXm2h9Dj3Aam2mk1/I yVz9qtRBCeUwPJvLuppQZ1tPh1wNF/M0wk2H0kFcMaW494zv0nqOIDNxkqSbMEQmjUea 75+vhXYpw5iWFueewPD4Dfi8med18ACHlSPt6m2ymPgltkfHVK/admZmG0+Ew04Rn3ps AxaQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=VZ1Nu4TClKywlJIX2MtkIO8a/JcUzUmevX6rOfNTQ4s=; b=LQsm/boSPB5QJUkd8d2n+RpMaAsa0qzEZhTXb/GP9brw6QkUKSKkjIAaKKzPZvpqks /rVPd+HNthENDFiCPS3naKFwnlWN1qdOf8I2iUxbTXzAJRLOnzyBWORM8YUYZH9JKOg2 nHHuSfdRlAE0Zec6aB7AL3Ob6QRuD1/DNNrmAlOxPu00B6Zc9XjzKIRuqXeJyyaTRq2/ T0Ch3sAExdDsomFBaos0gzrbDq6Z727hOLeRKgF8+YvCRBnXVvXlgscWdmuz0A4sGu9/ NGVWPx9pkLzBjtr+NcKAe8NDw6UIqcWNydFPUUPULUD50gH6SQwHvurMDS3u4jS8Ias1 JxOw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="R3K/eMQJ"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f1si16862298pgi.432.2019.06.26.05.25.42; Wed, 26 Jun 2019 05:25:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="R3K/eMQJ"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727470AbfFZMX1 (ORCPT + 99 others); Wed, 26 Jun 2019 08:23:27 -0400 Received: from mail-vk1-f201.google.com ([209.85.221.201]:55877 "EHLO mail-vk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726104AbfFZMX1 (ORCPT ); Wed, 26 Jun 2019 08:23:27 -0400 Received: by mail-vk1-f201.google.com with SMTP id b85so804030vke.22 for ; Wed, 26 Jun 2019 05:23: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=VZ1Nu4TClKywlJIX2MtkIO8a/JcUzUmevX6rOfNTQ4s=; b=R3K/eMQJQRtikm1dkDPsjm0vASp36psrk0zphCIGzfzKdobUSKP98DNPLmE3jtTz36 k53RvT9C4WPzIrAf7ogmvNgTJP4wcCVxNDiuaOfrQkNwQXRiv4gX3Sie3ymaWUgyagMg ySSkdoOWxJnKUXRr1FdQqhPlm4/2c1Z726b2YODRRqTL0VIS1JsdL1HX3mFeeiGmiAS/ ZZ47BRrNaqaviL/MHAk9Lv7rCAqpfm6krL2+Cx/hFK5eUZ+FOWrS8SnUejWx9ZAUtqxA /FEM2bkxjkcXiLiaM5BfOOoQj6y2Tm4lRbVetJavA7nYiXeYRy5l25bLE/DfavSm0Web 3Zfw== 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=VZ1Nu4TClKywlJIX2MtkIO8a/JcUzUmevX6rOfNTQ4s=; b=mVL9+ItiR9D7suGfo2vPRLHvIveOp+bA6e4EiSMEjx4xNoqjnPICQh365yWuAkHHiT gRIa223N6pywDCw3mWyIE+ktWUkCpkTqT89wiO+/4Heh5nRiIDC8BhWPGqa5mOeUGr9U Xiw3JeWyxYNOX0nHSnNruH4IhH061SzI3iziBCl421Pf/h1sJ/rrmks7mr5ZPGbfuBt8 WKsfGqvlT1wl5g7L5H0Fen10X80oHehy1wqW68ehPFmQE7Ymci/9+YZJpudPG/hJPxnJ vpSkpVzYufTcSLb2avPp+yQ34lhmuH7AX4l43W43aTs/edjfdKYgXo5XBQqB7+z7BUZG 4FDg== X-Gm-Message-State: APjAAAU7zwKERLT69JEtvGxkn4IA2uID8ghrLgMMNM/Jy4zAWYjnx97J v+LruPipsAzAYHi4wGiSDDc5KsEVgA== X-Received: by 2002:a1f:a887:: with SMTP id r129mr1048981vke.75.1561551806136; Wed, 26 Jun 2019 05:23:26 -0700 (PDT) Date: Wed, 26 Jun 2019 14:20:19 +0200 In-Reply-To: <20190626122018.171606-1-elver@google.com> Message-Id: <20190626122018.171606-5-elver@google.com> Mime-Version: 1.0 References: <20190626122018.171606-1-elver@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH v2 4/4] mm/kasan: Add object validation in ksize() From: Marco Elver To: aryabinin@virtuozzo.com, dvyukov@google.com, glider@google.com, andreyknvl@google.com Cc: linux-kernel@vger.kernel.org, Marco Elver , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , kasan-dev@googlegroups.com, linux-mm@kvack.org Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org ksize() has been unconditionally unpoisoning the whole shadow memory region associated with an allocation. This can lead to various undetected bugs, for example, double-kzfree(). Specifically, kzfree() uses ksize() to determine the actual allocation size, and subsequently zeroes the memory. Since ksize() used to just unpoison the whole shadow memory region, no invalid free was detected. This patch addresses this as follows: 1. Add a check in ksize(), and only then unpoison the memory region. 2. Preserve kasan_unpoison_slab() semantics by explicitly unpoisoning the shadow memory region using the size obtained from __ksize(). Tested: 1. With SLAB allocator: a) normal boot without warnings; b) verified the added double-kzfree() is detected. 2. With SLUB allocator: a) normal boot without warnings; b) verified the added double-kzfree() is detected. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199359 Signed-off-by: Marco Elver Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Alexander Potapenko Cc: Andrey Konovalov Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Cc: Andrew Morton Cc: kasan-dev@googlegroups.com Cc: linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org --- include/linux/kasan.h | 7 +++++-- mm/slab_common.c | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/linux/kasan.h b/include/linux/kasan.h index b40ea104dd36..cc8a03cc9674 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -76,8 +76,11 @@ void kasan_free_shadow(const struct vm_struct *vm); int kasan_add_zero_shadow(void *start, unsigned long size); void kasan_remove_zero_shadow(void *start, unsigned long size); -size_t ksize(const void *); -static inline void kasan_unpoison_slab(const void *ptr) { ksize(ptr); } +size_t __ksize(const void *); +static inline void kasan_unpoison_slab(const void *ptr) +{ + kasan_unpoison_shadow(ptr, __ksize(ptr)); +} size_t kasan_metadata_size(struct kmem_cache *cache); bool kasan_save_enable_multi_shot(void); diff --git a/mm/slab_common.c b/mm/slab_common.c index b7c6a40e436a..ba4a859261d5 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -1613,7 +1613,26 @@ EXPORT_SYMBOL(kzfree); */ size_t ksize(const void *objp) { - size_t size = __ksize(objp); + size_t size; + + BUG_ON(!objp); + /* + * We need to check that the pointed to object is valid, and only then + * unpoison the shadow memory below. We use __kasan_check_read(), to + * generate a more useful report at the time ksize() is called (rather + * than later where behaviour is undefined due to potential + * use-after-free or double-free). + * + * If the pointed to memory is invalid we return 0, to avoid users of + * ksize() writing to and potentially corrupting the memory region. + * + * We want to perform the check before __ksize(), to avoid potentially + * crashing in __ksize() due to accessing invalid metadata. + */ + if (unlikely(objp == ZERO_SIZE_PTR) || !__kasan_check_read(objp, 1)) + return 0; + + size = __ksize(objp); /* * We assume that ksize callers could use whole allocated area, * so we need to unpoison this area. -- 2.22.0.410.gd8fdbe21b5-goog