Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp30530imm; Thu, 31 May 2018 17:49:15 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJBzS+KegtkaIbzVRniVEgx+IrPY5ehn0ot/MImQlkaI3wLZDhiL9Igb25cDGmopOpgvO2k X-Received: by 2002:a65:4e85:: with SMTP id b5-v6mr7220277pgs.155.1527814155577; Thu, 31 May 2018 17:49:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527814155; cv=none; d=google.com; s=arc-20160816; b=b78zP4GwRlvEVldx/3gdCnqEkJRR3mi/Y0IZpRbHSnG0mJWnUzroglMqyF1E4Dl2zi oPaYZCzwyNKEmHeOgSXluNrjkirzr/Z6pYXizEGBA6ynfDu64/Mfv0fQJ0WWlqwh+X6o cr7g17ZzVnSff6m2yVZwikZeRsM8eGvmdhpxDUU44N2/5seq9DcjBMAkNBoqDpJteS6Y qVu1mGZ1yLbcvwhLjMQsyU2HshnkNXA1w+j9ZLjIbZboEk5MCBCYnqrOCBBrh8M0IwO2 Jet10/TFgzJYAsGLzZf5DrC7onF+qeiZ/v4gJYzEGkSFsx/KsgCCE/nxHsKoZvkUmuVN USSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=nOqvyg4ESECqEu7xshwH3mIkIyxetEA/GGDZ/hrFeaI=; b=0GyRW+JGWT0I5AVAVj98ZNxHOlaZFw2/lRQEn7E4mcuSHbTDGQ332sdj72bXe9gEYU TdqIBI3DE59xjOLkb+OGStjKOGjTusg1ZCmNece0Arn/WWrIzCdr+ykfUaMCsOeKQnzH vDR2tJiRvkkxcvkG3k6HB2u226Gj8TnG/8d0HhccVnZa4inGV7A0VbnC0Y/cVNIhhHDD 16d2id0GY2Z02p9NL2WKcgLiMe6XLjJymgBxygubPmFLdXvxuqT1Snv8QtP881DZGdZW Xu1WCyO9Zu2mKXhaP68ez3dRTWFjSH6OkxlXqXEe7rQBKaO/vxJR7X7gZO0eEnFHUhdJ Nlxw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=fbOqIZfk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t8-v6si38028676pfl.344.2018.05.31.17.49.01; Thu, 31 May 2018 17:49:15 -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=@chromium.org header.s=google header.b=fbOqIZfk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751417AbeFAAro (ORCPT + 99 others); Thu, 31 May 2018 20:47:44 -0400 Received: from mail-pg0-f66.google.com ([74.125.83.66]:43411 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751329AbeFAAnq (ORCPT ); Thu, 31 May 2018 20:43:46 -0400 Received: by mail-pg0-f66.google.com with SMTP id p8-v6so10448798pgq.10 for ; Thu, 31 May 2018 17:43:46 -0700 (PDT) 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=nOqvyg4ESECqEu7xshwH3mIkIyxetEA/GGDZ/hrFeaI=; b=fbOqIZfkXmAzKYHRQ7aRixekkLKMMufz5HIloAZ0E/YgBD9N5ofnelt7zQQWQVO80R C7rgGyDnHmrLo5HeakjctvDdwtjRDTiX13uYD6SE3YWzk3vVRYJmogeh1vDt0QSWrX4G X0KRl5pqlTKQDNVE0QngqK2C7wVurpdTMH0yE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nOqvyg4ESECqEu7xshwH3mIkIyxetEA/GGDZ/hrFeaI=; b=tUv/mp7nN2PFl2E+wqLAeS9PIZGJ856zC8a0ROLUHxKxUqBmoRqFTeoWYJN3NLd6a+ uiMOHWmjOsuzeFqZebhApMd26dcEjL6v+ER1uy4cWTXTCyI7ipdfcJBrUPjB+UUTpb/g xKQQXkMfo3i72jXy63WB0aE/Ivzm5bz60MIBUuDwd6loLXQz9IwvSuKefC381CfvCiri FWe+eRsifsxUuV9WEu+3jsPRjIAxs/H2bIF3NCg54aacnSjjsyEOjam2PuSDVpa+S4US H6FdOOstCLNvlorO6Sg/4cJeXlFNC0osxjxdAxVmG0aeoi/sJtysxurHftByiwPSGOsy rvjw== X-Gm-Message-State: ALKqPwdAhEIdCBsuosuqO8SXlJtqjUg32OpnB2CbuHgcBBRr4XjQ23JK Vjip6s1SQoVwba+pjj2L6M5/6g== X-Received: by 2002:a65:644f:: with SMTP id s15-v6mr7124729pgv.228.1527813825932; Thu, 31 May 2018 17:43:45 -0700 (PDT) Received: from www.outflux.net (173-164-112-133-Oregon.hfc.comcastbusiness.net. [173.164.112.133]) by smtp.gmail.com with ESMTPSA id v16-v6sm113148642pfk.164.2018.05.31.17.43.40 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 17:43:41 -0700 (PDT) From: Kees Cook To: Matthew Wilcox Cc: Kees Cook , Linus Torvalds , Rasmus Villemoes , Matthew Wilcox , LKML , Linux-MM , Kernel Hardening Subject: [PATCH v3 05/16] lib: overflow: Add memory allocation overflow tests Date: Thu, 31 May 2018 17:42:22 -0700 Message-Id: <20180601004233.37822-6-keescook@chromium.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180601004233.37822-1-keescook@chromium.org> References: <20180601004233.37822-1-keescook@chromium.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Make sure that the memory allocators are behaving as expected in the face of overflows. Signed-off-by: Kees Cook --- lib/test_overflow.c | 109 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/lib/test_overflow.c b/lib/test_overflow.c index 482d71c880fa..3f4457ea7d7c 100644 --- a/lib/test_overflow.c +++ b/lib/test_overflow.c @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #define DEFINE_TEST_ARRAY(t) \ static const struct test_ ## t { \ @@ -294,11 +297,117 @@ static int __init test_overflow_calculation(void) return err; } +/* + * Deal with the various forms of allocator arguments. See comments above + * the DEFINE_TEST_ALLOC() instances for mapping of the "bits". + */ +#define alloc010(alloc, arg, sz) alloc(sz, GFP_KERNEL) +#define alloc011(alloc, arg, sz) alloc(sz, GFP_KERNEL, NUMA_NO_NODE) +#define alloc000(alloc, arg, sz) alloc(sz) +#define alloc001(alloc, arg, sz) alloc(sz, NUMA_NO_NODE) +#define alloc110(alloc, arg, sz) alloc(arg, sz, GFP_KERNEL) +#define free0(free, arg, ptr) free(ptr) +#define free1(free, arg, ptr) free(arg, ptr) + +/* Wrap around to 8K */ +#define TEST_SIZE (9 << PAGE_SHIFT) + +#define DEFINE_TEST_ALLOC(func, free_func, want_arg, want_gfp, want_node)\ +static int __init test_ ## func (void *arg) \ +{ \ + volatile size_t a = TEST_SIZE; \ + volatile size_t b = (SIZE_MAX / TEST_SIZE) + 1; \ + void *ptr; \ + \ + /* Tiny allocation test. */ \ + ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg, 1);\ + if (!ptr) { \ + pr_warn(#func " failed regular allocation?!\n"); \ + return 1; \ + } \ + free ## want_arg (free_func, arg, ptr); \ + \ + /* Wrapped allocation test. */ \ + ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg, \ + a * b); \ + if (!ptr) { \ + pr_warn(#func " unexpectedly failed bad wrapping?!\n"); \ + return 1; \ + } \ + free ## want_arg (free_func, arg, ptr); \ + \ + /* Saturated allocation test. */ \ + ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg, \ + array_size(a, b)); \ + if (ptr) { \ + pr_warn(#func " missed saturation!\n"); \ + free ## want_arg (free_func, arg, ptr); \ + return 1; \ + } \ + pr_info(#func " detected saturation\n"); \ + return 0; \ +} + +/* + * Allocator uses a trailing node argument --------+ (e.g. kmalloc_node()) + * Allocator uses the gfp_t argument -----------+ | (e.g. kmalloc()) + * Allocator uses a special leading argument + | | (e.g. devm_kmalloc()) + * | | | + */ +DEFINE_TEST_ALLOC(kmalloc, kfree, 0, 1, 0); +DEFINE_TEST_ALLOC(kmalloc_node, kfree, 0, 1, 1); +DEFINE_TEST_ALLOC(kzalloc, kfree, 0, 1, 0); +DEFINE_TEST_ALLOC(kzalloc_node, kfree, 0, 1, 1); +DEFINE_TEST_ALLOC(vmalloc, vfree, 0, 0, 0); +DEFINE_TEST_ALLOC(vmalloc_node, vfree, 0, 0, 1); +DEFINE_TEST_ALLOC(vzalloc, vfree, 0, 0, 0); +DEFINE_TEST_ALLOC(vzalloc_node, vfree, 0, 0, 1); +DEFINE_TEST_ALLOC(kvmalloc, kvfree, 0, 1, 0); +DEFINE_TEST_ALLOC(kvmalloc_node, kvfree, 0, 1, 1); +DEFINE_TEST_ALLOC(kvzalloc, kvfree, 0, 1, 0); +DEFINE_TEST_ALLOC(kvzalloc_node, kvfree, 0, 1, 1); +DEFINE_TEST_ALLOC(devm_kmalloc, devm_kfree, 1, 1, 0); +DEFINE_TEST_ALLOC(devm_kzalloc, devm_kfree, 1, 1, 0); + +static int __init test_overflow_allocation(void) +{ + const char device_name[] = "overflow-test"; + struct device *dev; + int err = 0; + + /* Create dummy device for devm_kmalloc()-family tests. */ + dev = root_device_register(device_name); + if (!dev) { + pr_warn("Cannot register test device\n"); + return 1; + } + + err |= test_kmalloc(NULL); + err |= test_kmalloc_node(NULL); + err |= test_kzalloc(NULL); + err |= test_kzalloc_node(NULL); + err |= test_kvmalloc(NULL); + err |= test_kvmalloc_node(NULL); + err |= test_kvzalloc(NULL); + err |= test_kvzalloc_node(NULL); + err |= test_vmalloc(NULL); + err |= test_vmalloc_node(NULL); + err |= test_vzalloc(NULL); + err |= test_vzalloc_node(NULL); + err |= test_devm_kmalloc(dev); + err |= test_devm_kzalloc(dev); + + device_unregister(dev); + + return err; +} + static int __init test_module_init(void) { int err = 0; err |= test_overflow_calculation(); + err |= test_overflow_allocation(); if (err) { pr_warn("FAIL!\n"); -- 2.17.0