Received: by 2002:a25:f815:0:0:0:0:0 with SMTP id u21csp877532ybd; Wed, 26 Jun 2019 07:29:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqzUKWm4FbHplEWyD3JVsGe6Q2RhsT6E5PPXwgdQdWXsGd/Bfbnun5aQYrGPtU9B2EIkXkLr X-Received: by 2002:a63:5048:: with SMTP id q8mr1541116pgl.446.1561559340729; Wed, 26 Jun 2019 07:29:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561559340; cv=none; d=google.com; s=arc-20160816; b=eIa4Ny02+o5Eb7q7N31ou1lnInRwi7Fch7kVVKR/QGHtklrlOL3gqfbtBTjn8ygyS5 nEyueS8uxXWhqPSU4fTOKcenP411fpL1amlg6e+9Tba1hTebYutFCoxhl1Ou1FwNKzu0 ZouQXOi7rf+hZrwAluW/MLlzahrlXHskhl+e1vbNYKa+sgbTmGhcA/5IaH54JIgHgou7 Tg4jxibhgxuG5Z/BxWcDhkuyfBb+hqyISkW5zK59xjlW+mZq85C1oGHgPTl4H+041Ovh 3m1H4GDK6In62PeggEiocbYVl0nD6kyoUy/A6ICGb+kmHLYmB6wxG15jswDvKok+3z6X 4dBA== 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=faSJHauNDZMNHqAQEQyENlJrk267vkTV0fUxMXAvovc=; b=0iUH3lrYGwJyhM78p0KmKb1iEhx8tdwrrOO3N9BhSCCdb4s2JnsIyNpf8pBLYhocBS iii+6rEHcJkr4qlsr4II0140mhC99MPJs6rLG781vrSbtsveXjgucb0obFuP1r3J9GDI vV4JQouxQV2tW80j8iZbau4Yf31vOIJDYVc5NVQ/jx6NTuIPNLG+KvezFb26ySXA+D2d TJZagcR/mDqLvVySpkSegZeOBG+xVL1QgBZs/gMTlFcSCGnkhln+P6yirmHLp5PxGC+V EYfPTPWuCvUkt8lmciiPlqXdjb6FBqoGwP4DQxFFz88AVlRUUypFQO248qFbsxUhYlPo fs/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="Rpe/+hhA"; 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 m45si2216053pje.39.2019.06.26.07.28.44; Wed, 26 Jun 2019 07:29:00 -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="Rpe/+hhA"; 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 S1728098AbfFZO2M (ORCPT + 99 others); Wed, 26 Jun 2019 10:28:12 -0400 Received: from mail-yb1-f201.google.com ([209.85.219.201]:34343 "EHLO mail-yb1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728092AbfFZO2K (ORCPT ); Wed, 26 Jun 2019 10:28:10 -0400 Received: by mail-yb1-f201.google.com with SMTP id m11so6118385ybc.1 for ; Wed, 26 Jun 2019 07:28:09 -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=faSJHauNDZMNHqAQEQyENlJrk267vkTV0fUxMXAvovc=; b=Rpe/+hhAuik4wEKF7ZnhSFTzCJWomnStiupdaRm5p3WH78LIhaqN01wh0/La2gPWd0 GiWq87RjANNNVjijGXlI/D5fMC4N2f3aQ6pFE1DkTOd5HtLbPcPyYUoZAXnRJDsX1bUI HqUFzIbq50jIdzQAGS74aQswueJLB6Gj1rTKk9dLogJ+8knw6wW5Dq2QR5NV7avh8n5D CPnMn+dJ4Gy6aUdvTo04WvF/Hj8UgmAZmMypmXnFNRO0cyKFQCWldDBg7rbeuKvkIu2f 3x75GlN+HPPBvLh1hinwDSnWPmtIEZ3O5tvDaGybq/sHn4keSYz0bdMNtEu2NdTPDdeQ Eocw== 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=faSJHauNDZMNHqAQEQyENlJrk267vkTV0fUxMXAvovc=; b=VA/fyWl14WdpcZmZyv2QqZiVymGfar6lUoDT1B1Xi2/t3bh3EHOLdeIAOY4XbXDq6W /RNgoWYrbMRicR7GVmQ1MumAzFMS+y4xitClSUCl/W2sAtSn1zGGUwVCHYA80DIIcYvQ gSU0qIt6KxSwJpkqqzZSr57A1BEIC6qb02i/GqtP4Rd6CZYB30aP9uAykJx/WgmTbO8M O7FfY8WJ4dgD83uxzZXauQZ1wIO/uVYXugUQ2ZjtFoFNKvrXoPxC+f/P8Y/kijVSUe8k 6JMzOEXy1RZxSL+jqh3wmlK8nNCguhTH5e25r4EQUKx4EuSmQ2gTjFTE4s1zSoaHvJWk zOZg== X-Gm-Message-State: APjAAAXoKtaTEXvkT3cyMIKw4cHEtwMgtDuEalgXzDTHY5+HAFOJybpB rIAhP3Sbyt34IuOTvgWEB5i6Xp/dWA== X-Received: by 2002:a25:4d55:: with SMTP id a82mr2984762ybb.383.1561559289029; Wed, 26 Jun 2019 07:28:09 -0700 (PDT) Date: Wed, 26 Jun 2019 16:20:14 +0200 In-Reply-To: <20190626142014.141844-1-elver@google.com> Message-Id: <20190626142014.141844-6-elver@google.com> Mime-Version: 1.0 References: <20190626142014.141844-1-elver@google.com> X-Mailer: git-send-email 2.22.0.410.gd8fdbe21b5-goog Subject: [PATCH v3 5/5] mm/kasan: Add object validation in ksize() From: Marco Elver To: elver@google.com Cc: linux-kernel@vger.kernel.org, Andrey Ryabinin , Dmitry Vyukov , Alexander Potapenko , Andrey Konovalov , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , Andrew Morton , Mark Rutland , 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: Mark Rutland 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