{"id":816512,"url":"http://patchwork.ozlabs.org/api/patches/816512/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/patch/1505940337-79069-32-git-send-email-keescook@chromium.org/","project":{"id":7,"url":"http://patchwork.ozlabs.org/api/projects/7/?format=json","name":"Linux network development","link_name":"netdev","list_id":"netdev.vger.kernel.org","list_email":"netdev@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<1505940337-79069-32-git-send-email-keescook@chromium.org>","list_archive_url":null,"date":"2017-09-20T20:45:37","name":"[v3,31/31] lkdtm: Update usercopy tests for whitelisting","commit_ref":null,"pull_url":null,"state":"not-applicable","archived":true,"hash":"ddcdf72d1ef7ccdc42cd292e5e503da07af65039","submitter":{"id":10641,"url":"http://patchwork.ozlabs.org/api/people/10641/?format=json","name":"Kees Cook","email":"keescook@chromium.org"},"delegate":{"id":34,"url":"http://patchwork.ozlabs.org/api/users/34/?format=json","username":"davem","first_name":"David","last_name":"Miller","email":"davem@davemloft.net"},"mbox":"http://patchwork.ozlabs.org/project/netdev/patch/1505940337-79069-32-git-send-email-keescook@chromium.org/mbox/","series":[{"id":4231,"url":"http://patchwork.ozlabs.org/api/series/4231/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/list/?series=4231","date":"2017-09-20T20:45:22","name":"Hardened usercopy whitelisting","version":3,"mbox":"http://patchwork.ozlabs.org/series/4231/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/816512/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/816512/checks/","tags":{},"related":[],"headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"iMG30Frb\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xyBvZ0ZNkz9s8J\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu, 21 Sep 2017 06:59:54 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751823AbdITU7l (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tWed, 20 Sep 2017 16:59:41 -0400","from mail-pg0-f43.google.com ([74.125.83.43]:44392 \"EHLO\n\tmail-pg0-f43.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1752042AbdITUwu (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Wed, 20 Sep 2017 16:52:50 -0400","by mail-pg0-f43.google.com with SMTP id j16so2351290pga.1\n\tfor <netdev@vger.kernel.org>; Wed, 20 Sep 2017 13:52:50 -0700 (PDT)","from www.outflux.net\n\t(173-164-112-133-Oregon.hfc.comcastbusiness.net. [173.164.112.133])\n\tby smtp.gmail.com with ESMTPSA id\n\tl85sm10084211pfb.176.2017.09.20.13.52.45\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tWed, 20 Sep 2017 13:52:46 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=chromium.org; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=GAsEcpDb2hzKtslqhstNQZ9lXJIMCDKPyQvmcG8zmbk=;\n\tb=iMG30FrboMvyUywvs0/dszr2Bu6pN2m0+BgHv4aHysmTv4Tz40Sf5HqrKTnmllzOiM\n\tUpVA5s7l7Gd34D38toqsnCH/RHkLmw3ZzEZf6qeA4L+w0RyJVVZGB8daDgZWnS+aTRBx\n\tK/2qTBt4T58KSEcc77qmrlEeg0LydvzbEjx8E=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=GAsEcpDb2hzKtslqhstNQZ9lXJIMCDKPyQvmcG8zmbk=;\n\tb=pSEg9Euqv0xqwhujFHTyqmn0C5hNc1g+mrsgESI3VBCv77LgZX3eAexkbf3EjDM/5i\n\tjvuhx0OAhWhbRrbQMxn0phPjVeAIO4byM5Lf3AvtIXOaM0fXnzoajNMLYbSB+px9Gdjq\n\thf/NT+gMhJUZhe108K6AaI+UPSU2X9Dznar/caAvTLLqMnpcaZP0J8Vk1wVnfw0Qqho+\n\tA/2EbaL2Gyc6/p39RRx+tl4VPL33xl1dyYnrSZkxRtYQ1cPFzfMePoG7FSuz7RF+eYx5\n\tLAEgOhHIXJR+cakz+ZO4wqwzI34yZkcpwGCZhlSNgWbFtuW8PIX7cziVVrCo9WLFIXSz\n\t5sRw==","X-Gm-Message-State":"AHPjjUgMrnSXzp3RHjJ/at3nhhzskJn5U8AcUm3ju5oNxDgwm8MldrKp\n\tEjmZxGy0OXTjJN0yXLteaDgrBQ==","X-Google-Smtp-Source":"AOwi7QCyUY5BSf+LpB3oarwqVB5EadZ5010GkinZ/e1zhuplJWOIDVD+5VQeQ67Qo8ES1eAaFj56TQ==","X-Received":"by 10.84.129.68 with SMTP id 62mr3342721plb.186.1505940770110;\n\tWed, 20 Sep 2017 13:52:50 -0700 (PDT)","From":"Kees Cook <keescook@chromium.org>","To":"linux-kernel@vger.kernel.org","Cc":"Kees Cook <keescook@chromium.org>, linux-fsdevel@vger.kernel.org,\n\tnetdev@vger.kernel.org, linux-mm@kvack.org,\n\tkernel-hardening@lists.openwall.com, David Windsor <dave@nullcore.net>","Subject":"[PATCH v3 31/31] lkdtm: Update usercopy tests for whitelisting","Date":"Wed, 20 Sep 2017 13:45:37 -0700","Message-Id":"<1505940337-79069-32-git-send-email-keescook@chromium.org>","X-Mailer":"git-send-email 2.7.4","In-Reply-To":"<1505940337-79069-1-git-send-email-keescook@chromium.org>","References":"<1505940337-79069-1-git-send-email-keescook@chromium.org>","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"},"content":"This updates the USERCOPY_HEAP_FLAG_* tests to USERCOPY_HEAP_WHITELIST_*,\nsince the final form of usercopy whitelisting ended up using an offset/size\nwindow instead of the earlier proposed allocation flags.\n\nSigned-off-by: Kees Cook <keescook@chromium.org>\n---\n drivers/misc/lkdtm.h          |  4 +-\n drivers/misc/lkdtm_core.c     |  4 +-\n drivers/misc/lkdtm_usercopy.c | 88 ++++++++++++++++++++++++-------------------\n 3 files changed, 53 insertions(+), 43 deletions(-)","diff":"diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h\nindex bfb6c45b6130..327bcf46fab5 100644\n--- a/drivers/misc/lkdtm.h\n+++ b/drivers/misc/lkdtm.h\n@@ -75,8 +75,8 @@ void __init lkdtm_usercopy_init(void);\n void __exit lkdtm_usercopy_exit(void);\n void lkdtm_USERCOPY_HEAP_SIZE_TO(void);\n void lkdtm_USERCOPY_HEAP_SIZE_FROM(void);\n-void lkdtm_USERCOPY_HEAP_FLAG_TO(void);\n-void lkdtm_USERCOPY_HEAP_FLAG_FROM(void);\n+void lkdtm_USERCOPY_HEAP_WHITELIST_TO(void);\n+void lkdtm_USERCOPY_HEAP_WHITELIST_FROM(void);\n void lkdtm_USERCOPY_STACK_FRAME_TO(void);\n void lkdtm_USERCOPY_STACK_FRAME_FROM(void);\n void lkdtm_USERCOPY_STACK_BEYOND(void);\ndiff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c\nindex 981b3ef71e47..6e2d767ecaaa 100644\n--- a/drivers/misc/lkdtm_core.c\n+++ b/drivers/misc/lkdtm_core.c\n@@ -245,8 +245,8 @@ struct crashtype crashtypes[] = {\n \tCRASHTYPE(ATOMIC_TIMING),\n \tCRASHTYPE(USERCOPY_HEAP_SIZE_TO),\n \tCRASHTYPE(USERCOPY_HEAP_SIZE_FROM),\n-\tCRASHTYPE(USERCOPY_HEAP_FLAG_TO),\n-\tCRASHTYPE(USERCOPY_HEAP_FLAG_FROM),\n+\tCRASHTYPE(USERCOPY_HEAP_WHITELIST_TO),\n+\tCRASHTYPE(USERCOPY_HEAP_WHITELIST_FROM),\n \tCRASHTYPE(USERCOPY_STACK_FRAME_TO),\n \tCRASHTYPE(USERCOPY_STACK_FRAME_FROM),\n \tCRASHTYPE(USERCOPY_STACK_BEYOND),\ndiff --git a/drivers/misc/lkdtm_usercopy.c b/drivers/misc/lkdtm_usercopy.c\nindex df6ac985fbb5..f6055f4922bf 100644\n--- a/drivers/misc/lkdtm_usercopy.c\n+++ b/drivers/misc/lkdtm_usercopy.c\n@@ -19,7 +19,7 @@\n  */\n static volatile size_t unconst = 0;\n static volatile size_t cache_size = 1024;\n-static struct kmem_cache *bad_cache;\n+static struct kmem_cache *whitelist_cache;\n \n static const unsigned char test_text[] = \"This is a test.\\n\";\n \n@@ -114,6 +114,10 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame)\n \tvm_munmap(user_addr, PAGE_SIZE);\n }\n \n+/*\n+ * This checks for whole-object size validation with hardened usercopy,\n+ * with or without usercopy whitelisting.\n+ */\n static void do_usercopy_heap_size(bool to_user)\n {\n \tunsigned long user_addr;\n@@ -171,77 +175,79 @@ static void do_usercopy_heap_size(bool to_user)\n \tkfree(two);\n }\n \n-static void do_usercopy_heap_flag(bool to_user)\n+/*\n+ * This checks for the specific whitelist window within an object. If this\n+ * test passes, then do_usercopy_heap_size() tests will pass too.\n+ */\n+static void do_usercopy_heap_whitelist(bool to_user)\n {\n-\tunsigned long user_addr;\n-\tunsigned char *good_buf = NULL;\n-\tunsigned char *bad_buf = NULL;\n+\tunsigned long user_alloc;\n+\tunsigned char *buf = NULL;\n+\tunsigned char __user *user_addr;\n+\tsize_t offset, size;\n \n \t/* Make sure cache was prepared. */\n-\tif (!bad_cache) {\n+\tif (!whitelist_cache) {\n \t\tpr_warn(\"Failed to allocate kernel cache\\n\");\n \t\treturn;\n \t}\n \n \t/*\n-\t * Allocate one buffer from each cache (kmalloc will have the\n-\t * SLAB_USERCOPY flag already, but \"bad_cache\" won't).\n+\t * Allocate a buffer with a whitelisted window in the buffer.\n \t */\n-\tgood_buf = kmalloc(cache_size, GFP_KERNEL);\n-\tbad_buf = kmem_cache_alloc(bad_cache, GFP_KERNEL);\n-\tif (!good_buf || !bad_buf) {\n-\t\tpr_warn(\"Failed to allocate buffers from caches\\n\");\n+\tbuf = kmem_cache_alloc(whitelist_cache, GFP_KERNEL);\n+\tif (!buf) {\n+\t\tpr_warn(\"Failed to allocate buffer from whitelist cache\\n\");\n \t\tgoto free_alloc;\n \t}\n \n \t/* Allocate user memory we'll poke at. */\n-\tuser_addr = vm_mmap(NULL, 0, PAGE_SIZE,\n+\tuser_alloc = vm_mmap(NULL, 0, PAGE_SIZE,\n \t\t\t    PROT_READ | PROT_WRITE | PROT_EXEC,\n \t\t\t    MAP_ANONYMOUS | MAP_PRIVATE, 0);\n-\tif (user_addr >= TASK_SIZE) {\n+\tif (user_alloc >= TASK_SIZE) {\n \t\tpr_warn(\"Failed to allocate user memory\\n\");\n \t\tgoto free_alloc;\n \t}\n+\tuser_addr = (void __user *)user_alloc;\n \n-\tmemset(good_buf, 'A', cache_size);\n-\tmemset(bad_buf, 'B', cache_size);\n+\tmemset(buf, 'B', cache_size);\n+\n+\t/* Whitelisted window in buffer, from kmem_cache_create_usercopy. */\n+\toffset = (cache_size / 4) + unconst;\n+\tsize = (cache_size / 16) + unconst;\n \n \tif (to_user) {\n-\t\tpr_info(\"attempting good copy_to_user with SLAB_USERCOPY\\n\");\n-\t\tif (copy_to_user((void __user *)user_addr, good_buf,\n-\t\t\t\t cache_size)) {\n+\t\tpr_info(\"attempting good copy_to_user inside whitelist\\n\");\n+\t\tif (copy_to_user(user_addr, buf + offset, size)) {\n \t\t\tpr_warn(\"copy_to_user failed unexpectedly?!\\n\");\n \t\t\tgoto free_user;\n \t\t}\n \n-\t\tpr_info(\"attempting bad copy_to_user w/o SLAB_USERCOPY\\n\");\n-\t\tif (copy_to_user((void __user *)user_addr, bad_buf,\n-\t\t\t\t cache_size)) {\n+\t\tpr_info(\"attempting bad copy_to_user outside whitelist\\n\");\n+\t\tif (copy_to_user(user_addr, buf + offset - 1, size)) {\n \t\t\tpr_warn(\"copy_to_user failed, but lacked Oops\\n\");\n \t\t\tgoto free_user;\n \t\t}\n \t} else {\n-\t\tpr_info(\"attempting good copy_from_user with SLAB_USERCOPY\\n\");\n-\t\tif (copy_from_user(good_buf, (void __user *)user_addr,\n-\t\t\t\t   cache_size)) {\n+\t\tpr_info(\"attempting good copy_from_user inside whitelist\\n\");\n+\t\tif (copy_from_user(buf + offset, user_addr, size)) {\n \t\t\tpr_warn(\"copy_from_user failed unexpectedly?!\\n\");\n \t\t\tgoto free_user;\n \t\t}\n \n-\t\tpr_info(\"attempting bad copy_from_user w/o SLAB_USERCOPY\\n\");\n-\t\tif (copy_from_user(bad_buf, (void __user *)user_addr,\n-\t\t\t\t   cache_size)) {\n+\t\tpr_info(\"attempting bad copy_from_user outside whitelist\\n\");\n+\t\tif (copy_from_user(buf + offset - 1, user_addr, size)) {\n \t\t\tpr_warn(\"copy_from_user failed, but lacked Oops\\n\");\n \t\t\tgoto free_user;\n \t\t}\n \t}\n \n free_user:\n-\tvm_munmap(user_addr, PAGE_SIZE);\n+\tvm_munmap(user_alloc, PAGE_SIZE);\n free_alloc:\n-\tif (bad_buf)\n-\t\tkmem_cache_free(bad_cache, bad_buf);\n-\tkfree(good_buf);\n+\tif (buf)\n+\t\tkmem_cache_free(whitelist_cache, buf);\n }\n \n /* Callable tests. */\n@@ -255,14 +261,14 @@ void lkdtm_USERCOPY_HEAP_SIZE_FROM(void)\n \tdo_usercopy_heap_size(false);\n }\n \n-void lkdtm_USERCOPY_HEAP_FLAG_TO(void)\n+void lkdtm_USERCOPY_HEAP_WHITELIST_TO(void)\n {\n-\tdo_usercopy_heap_flag(true);\n+\tdo_usercopy_heap_whitelist(true);\n }\n \n-void lkdtm_USERCOPY_HEAP_FLAG_FROM(void)\n+void lkdtm_USERCOPY_HEAP_WHITELIST_FROM(void)\n {\n-\tdo_usercopy_heap_flag(false);\n+\tdo_usercopy_heap_whitelist(false);\n }\n \n void lkdtm_USERCOPY_STACK_FRAME_TO(void)\n@@ -313,11 +319,15 @@ void lkdtm_USERCOPY_KERNEL(void)\n void __init lkdtm_usercopy_init(void)\n {\n \t/* Prepare cache that lacks SLAB_USERCOPY flag. */\n-\tbad_cache = kmem_cache_create(\"lkdtm-no-usercopy\", cache_size, 0,\n-\t\t\t\t      0, NULL);\n+\twhitelist_cache =\n+\t\tkmem_cache_create_usercopy(\"lkdtm-usercopy\", cache_size,\n+\t\t\t\t\t   0, 0,\n+\t\t\t\t\t   cache_size / 4,\n+\t\t\t\t\t   cache_size / 16,\n+\t\t\t\t\t   NULL);\n }\n \n void __exit lkdtm_usercopy_exit(void)\n {\n-\tkmem_cache_destroy(bad_cache);\n+\tkmem_cache_destroy(whitelist_cache);\n }\n","prefixes":["v3","31/31"]}