From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932452AbcEFMp3 (ORCPT ); Fri, 6 May 2016 08:45:29 -0400 Received: from mail-am1on0101.outbound.protection.outlook.com ([157.56.112.101]:37636 "EHLO emea01-am1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1758709AbcEFMpN (ORCPT ); Fri, 6 May 2016 08:45:13 -0400 Authentication-Results: linux-foundation.org; dkim=none (message not signed) header.d=none;linux-foundation.org; dmarc=none action=none header.from=virtuozzo.com; From: Andrey Ryabinin To: Andrew Morton CC: , , , Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , Subject: [PATCH 4/4] x86/kasan: Instrument user memory access API Date: Fri, 6 May 2016 15:45:22 +0300 Message-ID: <1462538722-1574-4-git-send-email-aryabinin@virtuozzo.com> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1462538722-1574-1-git-send-email-aryabinin@virtuozzo.com> References: <1462538722-1574-1-git-send-email-aryabinin@virtuozzo.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [195.214.232.10] X-ClientProxiedBy: AM3PR07CA0025.eurprd07.prod.outlook.com (10.141.45.153) To DB6PR0801MB1303.eurprd08.prod.outlook.com (10.168.11.21) X-MS-Office365-Filtering-Correlation-Id: 64984153-3548-49e6-98cf-08d375ac41c4 X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1303;2:7ISt9PyKY6DZ0kPsfGGcQPFe+bfSV34lhE0XxFv5fRB/GbbiTZHVNZNl7U8IPWnJB77ytyFpAi7BKuMBd1Oo0HAIYn9fwFJB6PDvpbCbinu66x5i5UKTWhHqX/Vj/LbcSruYffNqMa5WF/fsMOp1LYoZRNJBxnIp4WfmCW1A7w1uujYBMwe6QkqnBJ2BmUo0;3:UonzwiEqJT0EZXKzcwLMo/FEE2FkwMuwdMG2kyVi2tRyHOcXnxbI/ZU9uzSlO4Iv/CK79ZRMfRM2D7kzQKbkBk8df7KS5dPk1enh4D+6DRigyWjJiqnnBKe1ZxdqJzfR;25:lgPgt0Ifmwhv3I/aQwmrqtjmTZ/52d+HbWsmWVoxlV4t4CBSlt3w9DlyJwvq2Tcm2DnfKR5OFr9ftSY83ydh3ZKN74hhvxhL/vXNIWcCl+EPZaVUoXTMBGl3wi37HVtuGQ1AGUrBDpSckmzRjxwUO1KTXGnbcWPPCiHdCSbI8mYIoznzPowUM04Hzr3zvPa77ZtABCDANpFAKyVFpaEiUy2RPRXjscDbj+03KqToBidS34x/s+qbJrdn87+rN3Lbk2cy40ecCKMZZRnM+N9IBYPtqXNMRspJ7ypQ023WTENGb/WEAY4DZDyT0KhHzIcPy2APh6GIZsDiiX65GWtwFYqJU+oO1wIRPTaAImyukyYxqhBAl9lmG2R8ElIGcva2WwxaFTSZmDowLqDxytth15c2JryxKhEnfvz5VFeofKvFkpwU+cmHqkGbsiOZKLty X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DB6PR0801MB1303; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040130)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6041072)(6043046);SRVR:DB6PR0801MB1303;BCL:0;PCL:0;RULEID:;SRVR:DB6PR0801MB1303; X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1303;4:9XnHyceMQJlxpN7T9BFIPDU5ZuElAhBzf3cTlF7aLFFWISfk7Pb7dWd36w4xICV2dmidMRFOwflWZmJiqZg/YvX2MtTxXunBkKN592zDc4YHuR9mA+AdITzH3PBZwBH3iYjRg1qHbH/qsXoptOPpJRPsiJ6vDZebGRGNtvLMvCVQ588KPTv6UopyqWg4v97a5g6TP4h60nIbtHg698EvHk7JPAr7hb9BmO+LLq+UFBHDdcJAp/cakWd0A2Ev2TFZ8AHhz5KYoOuiHSqLjwtmEncjHNQ3HJZSBQ0zpKvXKTBWN4WmKjfk+tjxJtA+JZ1hS2Huy7ja3G225hna7m9Y5m/WkuVD2T8TUri/TnxJQGsFU9Av+6QFYlOtj54NFXjgfwaUdUsI/SYsgEJEUwvcC71JS0vre3LdcWppRl7o9sI= X-Forefront-PRVS: 09347618C4 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6069001)(6009001)(33646002)(5008740100001)(2950100001)(47776003)(66066001)(2906002)(4326007)(92566002)(50226002)(77096005)(5004730100002)(110136002)(48376002)(76176999)(50986999)(19580405001)(586003)(50466002)(6116002)(42186005)(36756003)(189998001)(19580395003)(5003940100001)(86362001)(229853001)(81166005)(3846002)(53416004)(76506005);DIR:OUT;SFP:1102;SCL:1;SRVR:DB6PR0801MB1303;H:localhost.sw.ru;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1303;23:X9voS3GbhaGHGU62+RFM9ocp0MEn1c2xjRTa/ZKRlSIiFb+IPyGfHBfIUXiqHfRrCaWrf6VmzyCe80LIS0TXIdRVM9OJ1UUcobb5AJ2qeNcPbh2qa3lbBDJjNaQ3XG8FfMe1uSZ1jgiPL7FzCZgH3M4ZSrvRtYjzG/sz7BMZuGYy5znH+fNDjlPGKNzuV93+i97dAOKIGIyBedMEN+P/Gep7yN7JCNisAQ3qzIyYvTmKuLEq0b2F2evZb6bgUU9F9Iwkc96tE1CVUiTADyNbHAyW8ZgVGejvrylW0/1+T4gGyIWAsQ04hhpDT/gqkTIXTh6X20Ln+IWjSZC9InavuQQIijy4XaGQo1OOkSj3qgvg3S8hfBklOAhy2uIiNt9JNuRiA9QqhtyQToPTJz2bjz3Xwr34gIYHETLpWkrGmIhf9cNW5NZND9w8iljxPnnwAX2ovt+/d4Ug7QMIhluVgnT0ojpY5wwYbWWCSg5zc9Lgspufl5H/IRrrD7Il/d+bQ9/VEURpBxtq+ZhofGpulW3mb93H5TapwxK0PgcCcP0+uxhCtBzq9nyOiNXPE824hzSDTpgNS6i1TnnEREQXynA9035XNMSG9XW78m434xNMxQaomPQQrzeAP7pQeZ5TqL0S3lQ+Q+CbsLQ7TauFWOB3ngpk4MFyAxfdtmjuIOHv6nH5uAg5L0u1YwlgOXlXu4F15n2ImiLn41jYkF2lfQK1ldfywHrlrziUVKyXhpYXUYR7YMRI1R69cLq2pGp4cyXyEkSb2RTfjKFhFaXcKucPET2hB99dabur+H4al3Ww6vQJ+zcpwAdPu9USsxEGyRuLNSfUyO+w+sQJUf91x3wMRhamAhupSLnBgDsIDiInYWZ1iUVnzQh6M4ho7p4yZBYce4KNNfz7y0WjqGRSYw== X-Microsoft-Exchange-Diagnostics: 1;DB6PR0801MB1303;5:4EkgQnpsyt7X5GXAJSyHqjLnx0l+rdv5Q6i5dPkVTDTWtr95TogYnHb7W3Nixm2qR9+465C41r+TxaTSvtMsBYgOC+2qHkKDkZ9137WThAtG4h2ZJfPsquBE4T6Zd9KfhLGYbaY9wFs0+Uf8kWGkpw==;24:9ed6KXv71fAiAXDY1bVvZVAO8aB3f2Qg0zVgy+/HSpMxntd8h1yp7WsSTzDpbz6loKDgr7tQuB3rxYt/UY2tNP0YcofhWX9JrU0dRvtIL2I=;7:NXgZsH6kW3TmSgkeEh9n4bMBGkmV2fx0DajOc4W9IpYqBLOjAkkkp5QQAnxfGjm3BG7Z5MVh8NFNBrV3u2KbeIUPm06e4P09FsQK0K4iwfnqoqM3Oxh7JHP1v7lSYVefC3Kw53JMzIN7AVcOVZj2ZuS7OgijdZ7KIcbNmfmh2x/8I31gqdmSnrM3cjcK0tk3;20:dN0J2AnbriEyKT068qXjghUtWPGRPJIVMaTQkaaLdfWKuZ2T4x48ytc6edPxwhYjpXgw4Wm2in8wmgSVJei1iU6yL9XYg2OFWHrjVpyv0ynxLF4f5/HmVOx3NhdvqBPQGzTBb1YWg2pDiW64VrNvoYBWJ+66Arwz/uWbMRGH/pM= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 May 2016 12:45:07.8693 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0801MB1303 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Exchange between user and kernel memory is coded in assembly language. Which means that such accesses won't be spotted by KASAN as a compiler instruments only C code. Add explicit KASAN checks to user memory access API to ensure that userspace writes to (or reads from) a valid kernel memory. Note: Unlike others strncpy_from_user() is written mostly in C and KASAN sees memory accesses in it. However, it makes sense to add explicit check for all @count bytes that *potentially* could be written to the kernel. Signed-off-by: Andrey Ryabinin Cc: Alexander Potapenko Cc: Dmitry Vyukov Cc: x86@kernel.org --- arch/x86/include/asm/uaccess.h | 5 +++++ arch/x86/include/asm/uaccess_64.h | 7 +++++++ lib/strncpy_from_user.c | 2 ++ 3 files changed, 14 insertions(+) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 0b17fad..5dd6d18 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -5,6 +5,7 @@ */ #include #include +#include #include #include #include @@ -732,6 +733,8 @@ copy_from_user(void *to, const void __user *from, unsigned long n) might_fault(); + kasan_check_write(to, n); + /* * While we would like to have the compiler do the checking for us * even in the non-constant size case, any false positives there are @@ -765,6 +768,8 @@ copy_to_user(void __user *to, const void *from, unsigned long n) { int sz = __compiletime_object_size(from); + kasan_check_read(from, n); + might_fault(); /* See the comment in copy_from_user() above. */ diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 3076986..2eac2aa 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +110,7 @@ static __always_inline __must_check int __copy_from_user(void *dst, const void __user *src, unsigned size) { might_fault(); + kasan_check_write(dst, size); return __copy_from_user_nocheck(dst, src, size); } @@ -175,6 +177,7 @@ static __always_inline __must_check int __copy_to_user(void __user *dst, const void *src, unsigned size) { might_fault(); + kasan_check_read(src, size); return __copy_to_user_nocheck(dst, src, size); } @@ -242,12 +245,14 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size) static __must_check __always_inline int __copy_from_user_inatomic(void *dst, const void __user *src, unsigned size) { + kasan_check_write(dst, size); return __copy_from_user_nocheck(dst, src, size); } static __must_check __always_inline int __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size) { + kasan_check_read(src, size); return __copy_to_user_nocheck(dst, src, size); } @@ -258,6 +263,7 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src, unsigned size) { might_fault(); + kasan_check_write(dst, size); return __copy_user_nocache(dst, src, size, 1); } @@ -265,6 +271,7 @@ static inline int __copy_from_user_inatomic_nocache(void *dst, const void __user *src, unsigned size) { + kasan_check_write(dst, size); return __copy_user_nocache(dst, src, size, 0); } diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c index 3384032..e3472b0 100644 --- a/lib/strncpy_from_user.c +++ b/lib/strncpy_from_user.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -103,6 +104,7 @@ long strncpy_from_user(char *dst, const char __user *src, long count) if (unlikely(count <= 0)) return 0; + kasan_check_write(dst, count); max_addr = user_addr_max(); src_addr = (unsigned long)src; if (likely(src_addr < max_addr)) { -- 2.7.3