From patchwork Thu May 30 04:50:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 10968223 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E077914C0 for ; Thu, 30 May 2019 04:50:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D2D2328A3D for ; Thu, 30 May 2019 04:50:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C74D428A5E; Thu, 30 May 2019 04:50:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4AFC728A3D for ; Thu, 30 May 2019 04:50:35 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C263E6B0275; Thu, 30 May 2019 00:50:28 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id B88486B0274; Thu, 30 May 2019 00:50:28 -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 940CC6B0275; Thu, 30 May 2019 00:50:28 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf1-f197.google.com (mail-pf1-f197.google.com [209.85.210.197]) by kanga.kvack.org (Postfix) with ESMTP id 41CE66B0272 for ; Thu, 30 May 2019 00:50:28 -0400 (EDT) Received: by mail-pf1-f197.google.com with SMTP id 140so3672145pfa.23 for ; Wed, 29 May 2019 21:50:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:dkim-signature:from:to:cc:subject:date :message-id:in-reply-to:references; bh=wNjFOui7vuFEtKzXwg5aNy6ZEm6jbdXBcZyq2T1si6M=; b=kcYP9nSmOBOAHI9N4O0n3SiByufjoF+cCGXX+qiqiRuTp36NpPSUf7CXgxaRqqJYdr CKCn0GEMwx2v28dZfMlOrDWGgIiiibaCEHRFfI53qtxclBDWK/uX19XIxQVA9o6u4lGN x94oBw20cSSy8P/DVU2iCTVbX7Lsc9Cn8MQqYBz6gpp9sFn/w4Vj/USI5hqEhxOxpzZ1 nYm8Q8avBka1ve9Xf0krIjDMLh9bF7f5Cs99henQNuJ99ckiYCIoSx8/a1IHuI2blqnH t73kuTD8s8tmMFwEP6R8wV62TcKBKXWOvwWNGB+ZtlXwNvTFPof9jn5dqLgsC6IEnfhb Cr7g== X-Gm-Message-State: APjAAAW+9keUpUUt9K/FLToUFeGoD6eENhR/P5/fkTPPWrHQPdU5UyWE V7jrWHxgaJz2ZNIijOW+FYUcYE3i2VeFhmtiFiCKXMcKkHYKiPfgWc3B305FdPlH8BjGaNuE5oo 0wRh40sV8bOF3hCKXWhh2VUI4BKkXx5YiHzjZ8xCvDU9Xcb77NjSevAeRzWRgMXxKTw== X-Received: by 2002:a63:cb:: with SMTP id 194mr1923860pga.395.1559191827923; Wed, 29 May 2019 21:50:27 -0700 (PDT) X-Received: by 2002:a63:cb:: with SMTP id 194mr1923826pga.395.1559191827184; Wed, 29 May 2019 21:50:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559191827; cv=none; d=google.com; s=arc-20160816; b=AkKkTJX1cZ+SI+24S2MlVET5w496HxF0c1IQigc6tQM6IMxWxYXeLk7Dawpa5w93YG mj/W7Zj78b/7036Va9FkkkJPamD0TpIcTnf3i0/jeopsmXeJr54i4196aelftDY+my4Q x8Oe0p7kMimh6DjwE/15Gi+VqOoxpGLaSDY/mY/4sWv0oVEpryvN1BW5jmHTliV12XP8 Aad8bxyPNvNbc2HjzG08nR4Q1uUInjSY+LJN7pI3fa0xTwFPFg/Qy55967nKTw2OcBgu pJPTG1uU1oTqIn/IHoYiZ6kGB37DlxiItz6D//5bZNTtUSQA2XxTmuEuG18EYpPf5wn2 IDFg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=wNjFOui7vuFEtKzXwg5aNy6ZEm6jbdXBcZyq2T1si6M=; b=HDqRwsH6IkkYrIJmCcBpCrLZbbVdi03YKcxYCk43t6GGXwnJUHFlg5BbJanBjiRiVn e2y2TXhirKa6XZciu8kJAsKOqV0NhwkXsjlMfj8npwr0Q6H5UZ5NPuHdhkw6opa/uvWS tY1M2vlUFktOl26TxWJk1gmdQuWoZ5ob7PIXhhhMxVJ7MHTxBjOr6cgDkAvAdtPNei4I azmAK/tqo2PJ7rw7+wlVOjEOLO50+wwOIr+TRv/wsoljePXftKlqhgt6JjXCLWiExZIn V2ib5Kff/nCX3l+Wncn10Z3iOeu6mo8cuxw88QqnZNX3c9AHJaCZasrfk8idq2O83Iyb OvYw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=bLAFkJTI; spf=pass (google.com: domain of keescook@chromium.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id z135sor1940945pfc.19.2019.05.29.21.50.27 for (Google Transport Security); Wed, 29 May 2019 21:50:27 -0700 (PDT) Received-SPF: pass (google.com: domain of keescook@chromium.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=bLAFkJTI; spf=pass (google.com: domain of keescook@chromium.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wNjFOui7vuFEtKzXwg5aNy6ZEm6jbdXBcZyq2T1si6M=; b=bLAFkJTIqPVDEut/wCVyU9k9uP9Dw1+jlD0akLvS9pLrMPMZksl5uHLJxCejeJdj27 fdNCSAOKaQXtEbTCqgxLC96UX8hw8IWJTpfh3VeQscE8J+eOi5A46oWEmZzVDb5gO9Yu tv7gM97I5IOUlSQXxfAwAs+GLLp054KalnBrc= X-Google-Smtp-Source: APXvYqwP1CnFb/IRU8rVAJZSvTa5RJy0wsDR52/J/PPPSfS2jQkTxAG7Qw8Es+UFK9RLME6W5S2T5g== X-Received: by 2002:aa7:9095:: with SMTP id i21mr156634pfa.119.1559191826897; Wed, 29 May 2019 21:50:26 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id w12sm1361214pfj.41.2019.05.29.21.50.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 May 2019 21:50:24 -0700 (PDT) From: Kees Cook To: Andrew Morton Cc: Kees Cook , Matthew Wilcox , Alexander Popov , Alexander Potapenko , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH 1/3] mm/slab: Validate cache membership under freelist hardening Date: Wed, 29 May 2019 21:50:15 -0700 Message-Id: <20190530045017.15252-2-keescook@chromium.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190530045017.15252-1-keescook@chromium.org> References: <20190530045017.15252-1-keescook@chromium.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: X-Virus-Scanned: ClamAV using ClamSMTP When building under CONFIG_SLAB_FREELIST_HARDENING, it makes sense to perform sanity-checking on the assumed slab cache during kmem_cache_free() to make sure the kernel doesn't mix freelists across slab caches and corrupt memory (as seen in the exploitation of flaws like CVE-2018-9568[1]). Note that the prior code might WARN() but still corrupt memory (i.e. return the assumed cache instead of the owned cache). There is no noticeable performance impact (changes are within noise). Measuring parallel kernel builds, I saw the following with CONFIG_SLAB_FREELIST_HARDENED, before and after this patch: before: Run times: 288.85 286.53 287.09 287.07 287.21 Min: 286.53 Max: 288.85 Mean: 287.35 Std Dev: 0.79 after: Run times: 289.58 287.40 286.97 287.20 287.01 Min: 286.97 Max: 289.58 Mean: 287.63 Std Dev: 0.99 Delta: 0.1% which is well below the standard deviation [1] https://github.com/ThomasKing2014/slides/raw/master/Building%20universal%20Android%20rooting%20with%20a%20type%20confusion%20vulnerability.pdf Signed-off-by: Kees Cook --- mm/slab.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/mm/slab.h b/mm/slab.h index 43ac818b8592..4dafae2c8620 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -310,7 +310,7 @@ static inline bool is_root_cache(struct kmem_cache *s) static inline bool slab_equal_or_root(struct kmem_cache *s, struct kmem_cache *p) { - return true; + return s == p; } static inline const char *cache_name(struct kmem_cache *s) @@ -363,18 +363,16 @@ static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x) * will also be a constant. */ if (!memcg_kmem_enabled() && + !IS_ENABLED(CONFIG_SLAB_FREELIST_HARDENED) && !unlikely(s->flags & SLAB_CONSISTENCY_CHECKS)) return s; page = virt_to_head_page(x); cachep = page->slab_cache; - if (slab_equal_or_root(cachep, s)) - return cachep; - - pr_err("%s: Wrong slab cache. %s but object is from %s\n", - __func__, s->name, cachep->name); - WARN_ON_ONCE(1); - return s; + WARN_ONCE(!slab_equal_or_root(cachep, s), + "%s: Wrong slab cache. %s but object is from %s\n", + __func__, s->name, cachep->name); + return cachep; } static inline size_t slab_ksize(const struct kmem_cache *s) From patchwork Thu May 30 04:50:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 10968217 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EBF051398 for ; Thu, 30 May 2019 04:50:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D2571288AE for ; Thu, 30 May 2019 04:50:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C69E728A5B; Thu, 30 May 2019 04:50:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3CA33288AE for ; Thu, 30 May 2019 04:50:28 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2B0286B0271; Thu, 30 May 2019 00:50:27 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 23A006B0273; Thu, 30 May 2019 00:50: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 0B4076B0272; Thu, 30 May 2019 00:50:27 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pg1-f199.google.com (mail-pg1-f199.google.com [209.85.215.199]) by kanga.kvack.org (Postfix) with ESMTP id C3B086B026F for ; Thu, 30 May 2019 00:50:26 -0400 (EDT) Received: by mail-pg1-f199.google.com with SMTP id j26so1528150pgj.6 for ; Wed, 29 May 2019 21:50:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:dkim-signature:from:to:cc:subject:date :message-id:in-reply-to:references; bh=ro0eZo0iqlYxkBqPnVWAwPHhTLd6Yb2usUf2C4gK6mE=; b=qrGFTH1/lEt1ylpB2XPzVMjU6ir6HR32+gRTlGHhy+D4E9ab0naW4Vgo1by/y1OCuN MjY1mpsB6Z3KwyS1TGXjy6k1JvnpJXjncA2stplczbG+G3ReVml9Bcq5gDm+ri3FEGH/ zYgcu89D0oFGyjuoxYvAKTsUjrTITNrpf4k0S68dHtpL0v4YWMwwapeL04l4fSxlMCnK N3y1DCDtVBdFbVECrb5B3RRWE26n6HmW9cWoYKqnLHLig8jDKWNSA7Eqjz66dYPBJ/wy SWo+nAWwuBKDWFNTedl0T622PZJ0YU4SyxeTDs83PzBshLVV+JKPK7NgwGQ3I43qL6CH BNwg== X-Gm-Message-State: APjAAAXl6vlMgv55K4UPYB8DPV8PffXf3o4znAVWQsWp88uor/Y9tmND rARLvlt5xzMoFtZSUOR8Zooy8ot5W+6RxDWwJ21CeiMmjNdz/hyeLvJt0bIThBAJn4MQT/ZL+8h MhpzHMC59QZ5QZ0h1oWp7aBIEWPSQqwAltzNetIfHJ9j83yBqXUH9AfSqr9hfsrHsaA== X-Received: by 2002:a63:2c50:: with SMTP id s77mr1953501pgs.175.1559191826360; Wed, 29 May 2019 21:50:26 -0700 (PDT) X-Received: by 2002:a63:2c50:: with SMTP id s77mr1953464pgs.175.1559191825507; Wed, 29 May 2019 21:50:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559191825; cv=none; d=google.com; s=arc-20160816; b=GGy/M8XulyuwTjrfi4SdcCX8FGDS84yiSp2x7Dciws6Z3a6TKEONgyUghQRruhMKP1 3t4zUL/JyWCpRvt8lciZc/Uy/6jgCMyp+X7AZPuiTkRu4kGegbmy2hCJlWFHmkjq+mGy GKbLgfL6kejknHgxsadIQyBTPoUiiNs3tLd1ymjc/0XX9o2+5/VgEz/YviYq0raLAIZy 9K60w5ptWOCjb8/2nWZySr6TZdjIRsAcLOojDdQsIr53V0FrkLe5IqITEWI0zhVRNg8/ WwkbEPok4YHuU4LZ9kEbQwmM+58kklc2OYN4GRKV9cjC5M9wJtykUuaTL+Ltfh9vADuh nHKQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ro0eZo0iqlYxkBqPnVWAwPHhTLd6Yb2usUf2C4gK6mE=; b=DJMBGCIqU6oIburBmELvhCEpO2yK7SycmSYlgtH6/9GQa9KNP1NszCzwifWJRji9vb YHkzJ0vRa3qGLpgJ0d0jLtAq1fRavh/pgPI4G7yQCNXjnZ2WJzCfvMzxzeD24XcYhf/N 8l0LxcPjDdhX+9IyQZeLkS6O/pG7U0d0QcIn7NpCuaSfeRtVU+sFJuDV1wELxAQZaCs7 K2tLyavoYR351gDBSwQmiD5vBFVzQkWxbuMGdkFgvVApZP5bNYih3Pd5vW6BmDDajsDj O0aBP6RIB0Y6h+TkBRwPt1ICZmsYojEURonpGozqoX9ZXLyfgLsHKdcFsHJCXErFxhvY HaSA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=QxUyMepP; spf=pass (google.com: domain of keescook@chromium.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id l10sor1770913pgg.80.2019.05.29.21.50.25 for (Google Transport Security); Wed, 29 May 2019 21:50:25 -0700 (PDT) Received-SPF: pass (google.com: domain of keescook@chromium.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=QxUyMepP; spf=pass (google.com: domain of keescook@chromium.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ro0eZo0iqlYxkBqPnVWAwPHhTLd6Yb2usUf2C4gK6mE=; b=QxUyMepPmuFlBPWIdyq+hDUvIJEUHMM8hSMqXOaU5d+qk1TA2YsVTjyuk0Nq3LDdod JjwD0ZGD8M+YE/Y6QaRqXLENweWTFQfFepMCtYGmzHPzsVLJQ2RWsJ21V8QjF5O2Mqix c+CfgfD3OKGNqSm1uCtBNhVSJThW/A2BIVKxQ= X-Google-Smtp-Source: APXvYqx6yhz7sBMRnROF3lrt43atOsL36IzpXQDT7eajC7OfATKiWWEfU232CwKhSVYrVQa1CAtd9Q== X-Received: by 2002:a63:3141:: with SMTP id x62mr2022883pgx.282.1559191825131; Wed, 29 May 2019 21:50:25 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id l141sm1451014pfd.24.2019.05.29.21.50.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 May 2019 21:50:24 -0700 (PDT) From: Kees Cook To: Andrew Morton Cc: Kees Cook , Matthew Wilcox , Alexander Popov , Alexander Potapenko , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH 2/3] mm/slab: Sanity-check page type when looking up cache Date: Wed, 29 May 2019 21:50:16 -0700 Message-Id: <20190530045017.15252-3-keescook@chromium.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190530045017.15252-1-keescook@chromium.org> References: <20190530045017.15252-1-keescook@chromium.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: X-Virus-Scanned: ClamAV using ClamSMTP This avoids any possible type confusion when looking up an object. For example, if a non-slab were to be passed to kfree(), the invalid slab_cache pointer (i.e. overlapped with some other value from the struct page union) would be used for subsequent slab manipulations that could lead to further memory corruption. Since the page is already in cache, adding the PageSlab() check will have nearly zero cost, so add a check and WARN() to virt_to_cache(). Additionally replaces an open-coded virt_to_cache(). To support the failure mode this also updates all callers of virt_to_cache() and cache_from_obj() to handle a NULL cache pointer return value (though note that several already handle this case gracefully). Signed-off-by: Kees Cook --- mm/slab.c | 14 +++++++------- mm/slab.h | 17 +++++++++++++---- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index f7117ad9b3a3..9e3eee5568b6 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -371,12 +371,6 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp) static int slab_max_order = SLAB_MAX_ORDER_LO; static bool slab_max_order_set __initdata; -static inline struct kmem_cache *virt_to_cache(const void *obj) -{ - struct page *page = virt_to_head_page(obj); - return page->slab_cache; -} - static inline void *index_to_obj(struct kmem_cache *cache, struct page *page, unsigned int idx) { @@ -3715,6 +3709,8 @@ void kmem_cache_free_bulk(struct kmem_cache *orig_s, size_t size, void **p) s = virt_to_cache(objp); else s = cache_from_obj(orig_s, objp); + if (!s) + continue; debug_check_no_locks_freed(objp, s->object_size); if (!(s->flags & SLAB_DEBUG_OBJECTS)) @@ -3749,6 +3745,8 @@ void kfree(const void *objp) local_irq_save(flags); kfree_debugcheck(objp); c = virt_to_cache(objp); + if (!c) + return; debug_check_no_locks_freed(objp, c->object_size); debug_check_no_obj_freed(objp, c->object_size); @@ -4219,13 +4217,15 @@ void __check_heap_object(const void *ptr, unsigned long n, struct page *page, */ size_t ksize(const void *objp) { + struct kmem_cache *c; size_t size; BUG_ON(!objp); if (unlikely(objp == ZERO_SIZE_PTR)) return 0; - size = virt_to_cache(objp)->object_size; + c = virt_to_cache(objp); + size = c ? c->object_size : 0; /* We assume that ksize callers could use the whole allocated area, * so we need to unpoison this area. */ diff --git a/mm/slab.h b/mm/slab.h index 4dafae2c8620..739099af6cbb 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -350,10 +350,20 @@ static inline void memcg_link_cache(struct kmem_cache *s) #endif /* CONFIG_MEMCG_KMEM */ +static inline struct kmem_cache *virt_to_cache(const void *obj) +{ + struct page *page; + + page = virt_to_head_page(obj); + if (WARN_ONCE(!PageSlab(page), "%s: Object is not a Slab page!\n", + __func__)) + return NULL; + return page->slab_cache; +} + static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x) { struct kmem_cache *cachep; - struct page *page; /* * When kmemcg is not being used, both assignments should return the @@ -367,9 +377,8 @@ static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x) !unlikely(s->flags & SLAB_CONSISTENCY_CHECKS)) return s; - page = virt_to_head_page(x); - cachep = page->slab_cache; - WARN_ONCE(!slab_equal_or_root(cachep, s), + cachep = virt_to_cache(x); + WARN_ONCE(cachep && !slab_equal_or_root(cachep, s), "%s: Wrong slab cache. %s but object is from %s\n", __func__, s->name, cachep->name); return cachep; From patchwork Thu May 30 04:50:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 10968221 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AEBDF1398 for ; Thu, 30 May 2019 04:50:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A15E92838B for ; Thu, 30 May 2019 04:50:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 95FD028A5B; Thu, 30 May 2019 04:50:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0F3CD2838B for ; Thu, 30 May 2019 04:50:33 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 5E5C46B0273; Thu, 30 May 2019 00:50:28 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 56F256B0275; Thu, 30 May 2019 00:50:28 -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 411296B0274; Thu, 30 May 2019 00:50:28 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by kanga.kvack.org (Postfix) with ESMTP id F389E6B0272 for ; Thu, 30 May 2019 00:50:27 -0400 (EDT) Received: by mail-pl1-f197.google.com with SMTP id d22so3162179plr.0 for ; Wed, 29 May 2019 21:50:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:dkim-signature:from:to:cc:subject:date :message-id:in-reply-to:references; bh=0d2DjLTtSzc/j4GazSC/oBA3i3Oos8BMeCC9qu8DWTQ=; b=H3/Xyjlv30emWeHjzHjklwjlNuMi0BZlM1lxp8tYNT3KKJEbzI3RsyQiwJl94NZa0S TajAmEX6h870bl3ujX9O9OOAowo33tqA/ITO0f1VLps1fqTaZi6wSj87hlDCAdSc2GQZ scuL7/BePSAB3O2X6f0LpDkENY0gkb8VVZTf6CI7oBeFhhT0M6YXs8DwlcQJp9H+zeFh rwYJET2o2wQXkzHvbU0Jrngt2aOkhs9aC0P68t7G1Ex/GtfVM+inc+B5oCqkM63Rx5Jn rIDijYFNX4Hhj0PcGWpLRKqgvPU456tRuOGRZcRBLY6cUVOH9i5QZcpGrioNlkUn2bT3 Q29g== X-Gm-Message-State: APjAAAWb3YpOE7dlx6SfxzYj7oT2GlsnHfoVCSrtqb05fV2BWLNbu7hY XyAJ3mVCRdQUYiUXE3gHYVB7ASwoXKiMO+KC0rjzWWHOMsApvCMhtg0qhxwE/esVtfMelJyBKds 2+KEhgphgVl6oOYN64KM1C8bmcf78GYtAaG9uBUIM4XYeUMyuLKwPZHxDGGSJAfVyyQ== X-Received: by 2002:a63:c50c:: with SMTP id f12mr1961031pgd.71.1559191827572; Wed, 29 May 2019 21:50:27 -0700 (PDT) X-Received: by 2002:a63:c50c:: with SMTP id f12mr1961001pgd.71.1559191826660; Wed, 29 May 2019 21:50:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559191826; cv=none; d=google.com; s=arc-20160816; b=lgqIZQB69gqNcF07vkaR70AyKtizzUg0lVgxrOtLRrNYKBRFvomzfDuNJYE4kasWdQ hvHsKnJuXQEXEokEWwkOZ+Vlwh1ldb/ldlazLwFw0QsmUfAYSsGw8BkuiDeNoX6n4jp/ NTHchtmz+Z+aANg5DSf6jdtaLeUZ24JoKqnHhfIC+gXEu+uFSrhUFN4/wghXM7LSTZga bvOZzK9q7EBFipdLVxn3tJNvV8j7kA4NWlp6T2gGmm35tFFMI+0wuWaySwqUkmBm+hGc 5juZnoFyt4Ds+hzZ7c/HpVHl2lCl7QAwf3RKNpdqvjgrKQWFbu2wC8IHIIwW/J2mZn1o IPRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=0d2DjLTtSzc/j4GazSC/oBA3i3Oos8BMeCC9qu8DWTQ=; b=W7/CGyZ8r55JhpZRNIC9RYzZyKTWrSoXoc4A6P9Ytl5G3ymXtQPPQlKWtnmio07gQM bHldk1XxbCp+C2v5ajGDtkjmKw6xb+1ITADkfH9NL5OPWq9sitrFAqwRlwqyHDZDFzEy aMHcWnYfmu822e5INuqZIjUrEHZM8tXSH1suSYp3AVDxvupEEZNNiVsNqP0MP2kL9Wx4 UNBZ55oFuWDGzt011M1toQge7QHjyUqyI6RInmojmmmw+zPxT1m0w7pQvkkx5g1DndG0 9VNCAziras4eNsa4TWnmOYID6o/hia1kX3SyGKN/cu6nHnopkJ7qbOPMBT1pOMWa4Js5 YP5A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=CUCf1ofe; spf=pass (google.com: domain of keescook@chromium.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id e23sor1774536pgb.69.2019.05.29.21.50.26 for (Google Transport Security); Wed, 29 May 2019 21:50:26 -0700 (PDT) Received-SPF: pass (google.com: domain of keescook@chromium.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=CUCf1ofe; spf=pass (google.com: domain of keescook@chromium.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0d2DjLTtSzc/j4GazSC/oBA3i3Oos8BMeCC9qu8DWTQ=; b=CUCf1ofeWouCM5OzBk/IBw9EmIyAjfi5VZFZ/WBrN8Vklom9TEX+memXlAOdgMfFti ff8V2Y4FMs2V8ynl6NLjipV5OJsO3EvUHiIYYn7sDVlaFqUrrqojm8TL8uyFTCeFEY2l yJbNftijtrl4QLGvYLNSt1A/1l0b8F0qQ0ud8= X-Google-Smtp-Source: APXvYqwDsRz4qk6MfIpcfvDtSrrTWKmVd2sbAjLdyUwrbya7Z0brqCXAdyW7W1bnwSiib5kYONjLMg== X-Received: by 2002:a63:cc4b:: with SMTP id q11mr1994193pgi.43.1559191826365; Wed, 29 May 2019 21:50:26 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id f28sm1339930pfk.104.2019.05.29.21.50.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 May 2019 21:50:24 -0700 (PDT) From: Kees Cook To: Andrew Morton Cc: Kees Cook , Matthew Wilcox , Alexander Popov , Alexander Potapenko , Christoph Lameter , Pekka Enberg , David Rientjes , Joonsoo Kim , linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH 3/3] lkdtm/heap: Add tests for freelist hardening Date: Wed, 29 May 2019 21:50:17 -0700 Message-Id: <20190530045017.15252-4-keescook@chromium.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190530045017.15252-1-keescook@chromium.org> References: <20190530045017.15252-1-keescook@chromium.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: X-Virus-Scanned: ClamAV using ClamSMTP This adds tests for double free and cross-cache freeing, which should both be caught by CONFIG_SLAB_FREELIST_HARDENED. Signed-off-by: Kees Cook --- drivers/misc/lkdtm/core.c | 5 +++ drivers/misc/lkdtm/heap.c | 72 ++++++++++++++++++++++++++++++++++++++ drivers/misc/lkdtm/lkdtm.h | 5 +++ 3 files changed, 82 insertions(+) diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index 4f3a6e1cd331..b78df5a09217 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -133,6 +133,9 @@ static const struct crashtype crashtypes[] = { CRASHTYPE(READ_AFTER_FREE), CRASHTYPE(WRITE_BUDDY_AFTER_FREE), CRASHTYPE(READ_BUDDY_AFTER_FREE), + CRASHTYPE(SLAB_FREE_DOUBLE), + CRASHTYPE(SLAB_FREE_CROSS), + CRASHTYPE(SLAB_FREE_PAGE), CRASHTYPE(SOFTLOCKUP), CRASHTYPE(HARDLOCKUP), CRASHTYPE(SPINLOCKUP), @@ -439,6 +442,7 @@ static int __init lkdtm_module_init(void) lkdtm_bugs_init(&recur_count); lkdtm_perms_init(); lkdtm_usercopy_init(); + lkdtm_heap_init(); /* Register debugfs interface */ lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL); @@ -485,6 +489,7 @@ static void __exit lkdtm_module_exit(void) debugfs_remove_recursive(lkdtm_debugfs_root); /* Handle test-specific clean-up. */ + lkdtm_heap_exit(); lkdtm_usercopy_exit(); if (lkdtm_kprobe != NULL) diff --git a/drivers/misc/lkdtm/heap.c b/drivers/misc/lkdtm/heap.c index 65026d7de130..3c5cec85edce 100644 --- a/drivers/misc/lkdtm/heap.c +++ b/drivers/misc/lkdtm/heap.c @@ -7,6 +7,10 @@ #include #include +static struct kmem_cache *double_free_cache; +static struct kmem_cache *a_cache; +static struct kmem_cache *b_cache; + /* * This tries to stay within the next largest power-of-2 kmalloc cache * to avoid actually overwriting anything important if it's not detected @@ -146,3 +150,71 @@ void lkdtm_READ_BUDDY_AFTER_FREE(void) kfree(val); } + +void lkdtm_SLAB_FREE_DOUBLE(void) +{ + int *val; + + val = kmem_cache_alloc(double_free_cache, GFP_KERNEL); + if (!val) { + pr_info("Unable to allocate double_free_cache memory.\n"); + return; + } + + /* Just make sure we got real memory. */ + *val = 0x12345678; + pr_info("Attempting double slab free ...\n"); + kmem_cache_free(double_free_cache, val); + kmem_cache_free(double_free_cache, val); +} + +void lkdtm_SLAB_FREE_CROSS(void) +{ + int *val; + + val = kmem_cache_alloc(a_cache, GFP_KERNEL); + if (!val) { + pr_info("Unable to allocate a_cache memory.\n"); + return; + } + + /* Just make sure we got real memory. */ + *val = 0x12345679; + pr_info("Attempting cross-cache slab free ...\n"); + kmem_cache_free(b_cache, val); +} + +void lkdtm_SLAB_FREE_PAGE(void) +{ + unsigned long p = __get_free_page(GFP_KERNEL); + + pr_info("Attempting non-Slab slab free ...\n"); + kmem_cache_free(NULL, (void *)p); + free_page(p); +} + +/* + * We have constructors to keep the caches distinctly separated without + * needing to boot with "slab_nomerge". + */ +static void ctor_double_free(void *region) +{ } +static void ctor_a(void *region) +{ } +static void ctor_b(void *region) +{ } + +void __init lkdtm_heap_init(void) +{ + double_free_cache = kmem_cache_create("lkdtm-heap-double_free", + 64, 0, 0, ctor_double_free); + a_cache = kmem_cache_create("lkdtm-heap-a", 64, 0, 0, ctor_a); + b_cache = kmem_cache_create("lkdtm-heap-b", 64, 0, 0, ctor_b); +} + +void __exit lkdtm_heap_exit(void) +{ + kmem_cache_destroy(double_free_cache); + kmem_cache_destroy(a_cache); + kmem_cache_destroy(b_cache); +} diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h index 23dc565b4307..c5ae0b37587d 100644 --- a/drivers/misc/lkdtm/lkdtm.h +++ b/drivers/misc/lkdtm/lkdtm.h @@ -28,11 +28,16 @@ void lkdtm_STACK_GUARD_PAGE_LEADING(void); void lkdtm_STACK_GUARD_PAGE_TRAILING(void); /* lkdtm_heap.c */ +void __init lkdtm_heap_init(void); +void __exit lkdtm_heap_exit(void); void lkdtm_OVERWRITE_ALLOCATION(void); void lkdtm_WRITE_AFTER_FREE(void); void lkdtm_READ_AFTER_FREE(void); void lkdtm_WRITE_BUDDY_AFTER_FREE(void); void lkdtm_READ_BUDDY_AFTER_FREE(void); +void lkdtm_SLAB_FREE_DOUBLE(void); +void lkdtm_SLAB_FREE_CROSS(void); +void lkdtm_SLAB_FREE_PAGE(void); /* lkdtm_perms.c */ void __init lkdtm_perms_init(void);