From patchwork Wed Nov 1 21:36:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laura Abbott X-Patchwork-Id: 10037375 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 448A76032D for ; Wed, 1 Nov 2017 21:37:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3CDA228522 for ; Wed, 1 Nov 2017 21:37:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 314EA28BFB; Wed, 1 Nov 2017 21:37:27 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 52D9F28522 for ; Wed, 1 Nov 2017 21:37:25 +0000 (UTC) Received: (qmail 22283 invoked by uid 550); 1 Nov 2017 21:37:24 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 22252 invoked from network); 1 Nov 2017 21:37:23 -0000 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; bh=10X3AUjd1Be73zWwnUlnjpmEZ0bvyl549bGM58OdB8w=; b=tCXoXvh5tMF4e5OY3c9XYFJOqWGyooNMgRC4Kvftvd6uVeirZGBzz4LK8jmEWjFV0i pxoVXLSw4RjHAK4e9SNSpkL+vLtwruGQGfDTYB87Qi00GfDsvCTGGA0rMbWqhVAjJObr mZOwljdP3vuhk9vVFF0/veWdqjGVgS3n6keKiBbOqmqdgkH7aKhBwcJ/+dthXYwgS05a +BPpetjj/+c4VyMhKMUaszlbP/0Xgw8/2sGgbsWNnfv1bGd5GyjUx4skD1C8E8hW7dkJ KhjObMytoo/8SwjsxYU06YUsco7OyQLdfF3l/gKQC0UAv1qrIyoB3GcUmuLRXsKOuYkU cMfw== X-Gm-Message-State: AJaThX5f6/dARlASKevJy5e+dqvh33ftn2uWAZbVj6aIR9KDNttl2YIK WnX70zhI5dfe7E0tRKVcAkuRjQ== X-Google-Smtp-Source: ABhQp+R23NKrzhVCOYsB/RG0sEkkdt9Ko256NS4/CbOfR8PiuZ7ctHI4eKL8dg7sNTOdIrPTvJRjJw== X-Received: by 10.157.9.66 with SMTP id 60mr727242otp.56.1509572231535; Wed, 01 Nov 2017 14:37:11 -0700 (PDT) From: Laura Abbott To: Kees Cook Cc: Laura Abbott , linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com Date: Wed, 1 Nov 2017 14:36:58 -0700 Message-Id: <20171101213658.11267-1-labbott@redhat.com> X-Mailer: git-send-email 2.13.5 Subject: [kernel-hardening] [PATCH] lkdtm: Add tests for put_user/get_user X-Virus-Scanned: ClamAV using ClamSMTP {get,put}_user are designed to be 'safe' access and verify the address passed in whereas __{get,put}_user are supposed to be 'unsafe'. Add a test to verify this behavior. Signed-off-by: Laura Abbott --- Inspired by the paranoid __{get,put}_user checks for arm64. --- drivers/misc/lkdtm.h | 2 + drivers/misc/lkdtm_core.c | 2 + drivers/misc/lkdtm_usercopy.c | 107 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index bfb6c45b6130..c80236198c96 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h @@ -81,5 +81,7 @@ void lkdtm_USERCOPY_STACK_FRAME_TO(void); void lkdtm_USERCOPY_STACK_FRAME_FROM(void); void lkdtm_USERCOPY_STACK_BEYOND(void); void lkdtm_USERCOPY_KERNEL(void); +void lkdtm_PUT_USER(void); +void lkdtm_GET_USER(void); #endif diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 981b3ef71e47..f0a99ccc2a5a 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c @@ -251,6 +251,8 @@ struct crashtype crashtypes[] = { CRASHTYPE(USERCOPY_STACK_FRAME_FROM), CRASHTYPE(USERCOPY_STACK_BEYOND), CRASHTYPE(USERCOPY_KERNEL), + CRASHTYPE(PUT_USER), + CRASHTYPE(GET_USER), }; diff --git a/drivers/misc/lkdtm_usercopy.c b/drivers/misc/lkdtm_usercopy.c index df6ac985fbb5..3a95a85cafdb 100644 --- a/drivers/misc/lkdtm_usercopy.c +++ b/drivers/misc/lkdtm_usercopy.c @@ -310,6 +310,113 @@ void lkdtm_USERCOPY_KERNEL(void) vm_munmap(user_addr, PAGE_SIZE); } +void lkdtm_PUT_USER(void) +{ + unsigned long user_addr; + void *kbuf; + + kbuf = kmalloc(cache_size, GFP_KERNEL); + if (!kbuf) { + pr_warn("failed to allocate kernel buffer\n"); + return; + } + + user_addr = vm_mmap(NULL, 0, PAGE_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANONYMOUS | MAP_PRIVATE, 0); + if (user_addr >= TASK_SIZE) { + pr_warn("Failed to allocate user memory\n"); + goto free_kernel; + } + + pr_info("attempting valid put_user\n"); + if (put_user(0x1234567, (unsigned long __user *)user_addr)) { + pr_warn("put_user failed unexpectedly?!\n"); + goto free_user; + } + + + pr_info("attempting valid __put_user\n"); + if (__put_user(0x1234567, (unsigned long __user *)user_addr)) { + pr_warn("__put_user failed unexpectedly?!\n"); + goto free_user; + } + + pr_info("attempting invalid put_user which should fail"); + if (put_user(0x1234567, (unsigned long *)kbuf)) { + pr_warn("put_user failed correctly\n"); + } else { + pr_warn("put_user succeeded unexpectedly\n"); + goto free_user; + } + + + pr_info("attempting invalid __put_user which should succeed\n"); + if (__put_user(0x1234567, (unsigned long *)kbuf)) { + pr_warn("__put_user failed unexpectedly\n"); + } else { + pr_warn("__put_user succeeded\n"); + } + +free_user: + vm_munmap(user_addr, PAGE_SIZE); +free_kernel: + kfree(kbuf); +} + +void lkdtm_GET_USER(void) +{ + unsigned long user_addr; + unsigned long a; + void *kbuf; + + kbuf = kmalloc(cache_size, GFP_KERNEL); + if (!kbuf) { + pr_warn("failed to allocate kernel buffer\n"); + return; + } + + user_addr = vm_mmap(NULL, 0, PAGE_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANONYMOUS | MAP_PRIVATE, 0); + if (user_addr >= TASK_SIZE) { + pr_warn("Failed to allocate user memory\n"); + goto free_kernel; + } + + pr_info("attempting valid get_user\n"); + if (get_user(a, (unsigned long __user *)user_addr)) { + pr_warn("get_user failed unexpectedly?!\n"); + goto free_user; + } + + pr_info("attempting valid __get_user\n"); + if (__get_user(a, (unsigned long __user *)user_addr)) { + pr_warn("__get_user failed unexpectedly?!\n"); + goto free_user; + } + + pr_info("attempting an invalid get_user which should fail\n"); + if (get_user(a, (unsigned long *)kbuf)) { + pr_warn("get_user failed correctly\n"); + } else { + pr_warn("get_user succeeded unexpectedly\n"); + goto free_user; + } + + pr_info("attempting an invalid __get_user which should succeed\n"); + if (__get_user(a, (unsigned long *)kbuf)) { + pr_warn("get_user failed unexpectedly\n"); + } else { + pr_warn("get_user succeeded\n"); + } + +free_user: + vm_munmap(user_addr, PAGE_SIZE); +free_kernel: + kfree(kbuf); +} + void __init lkdtm_usercopy_init(void) { /* Prepare cache that lacks SLAB_USERCOPY flag. */