Received: by 2002:a25:c205:0:0:0:0:0 with SMTP id s5csp1097501ybf; Thu, 27 Feb 2020 05:02:54 -0800 (PST) X-Google-Smtp-Source: APXvYqyDqdj+Iw9ohIkfJOXOKfHGtWEVahH/NA4IRuBsChYO7NvRNvG1+wyvUVGQ40dlaTUE7NiK X-Received: by 2002:a05:6808:b39:: with SMTP id t25mr3205671oij.71.1582808574385; Thu, 27 Feb 2020 05:02:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1582808574; cv=none; d=google.com; s=arc-20160816; b=YDAt0uwQ41icpQhQsShcsN5/XnK0P+d4zjYGrviThNyIFheNiwV+5jJuRF7wd8PqMm XwEWuGF/WcR05bVTyG1W7rdSxH2+RVkOpa6HmLI5ZnSXmMiqbrXXZEuqA9EJCPStrffS xlGegnE9kSS1B9JXmQy+M24erdK4h2rq/iuUNLF4+IzVyI9PgWJN83itxRpB1KGw2A2V UkKBt+qCfrmawKGckMHCuTsnBLBlVZrcmUZx77iPBFIFI5CM4bLJTdR9F+VS+y+W7rI0 5gIRHSu432eFZK7UUc9dM3UouZuziJnkFvB9AmRUB7x8bk3sLZrwZPAEhRfjaPc4xWT9 3/FQ== 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; bh=jeUOX0+k6ZxijKxn58fp6D0LxYjyFNJKfCHA9GisEeI=; b=jkBGc9md1hCUSyiKXIuqO96uWikdhucaMdtu27/ABw9mNBrwiJ2nN2k/r6EOZ954j5 bwV3rIeftviGFar+reVvBdBh8CPgOcZnRo7r6ycLIYhRxW/6slu4a7Rt23VEO8alAEan JwUpUhvzY1sFiv/gK7RZl6vG5OAu2gE8PJ2fZuldP0WVDGyPSoW/0rEMmykFuhGzAGjl A/FHe4KZmJ78vKxFpUepz8OgdIHhwuj+/OrQtMjhgKVxW5MN/sjKEz3YnSOaR0o2JjUR vc6Fkn4T4Eb3Q96O/6frU0U63PD7Li4VEJ/rnrx48xQQcQdJU0jFQm+5JTs302CmUxMa wD3w== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d3si1182782oia.236.2020.02.27.05.02.38; Thu, 27 Feb 2020 05:02:54 -0800 (PST) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729127AbgB0NC1 (ORCPT + 99 others); Thu, 27 Feb 2020 08:02:27 -0500 Received: from mx2.suse.de ([195.135.220.15]:37336 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729121AbgB0NC1 (ORCPT ); Thu, 27 Feb 2020 08:02:27 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 7AF68B310; Thu, 27 Feb 2020 13:02:25 +0000 (UTC) From: Petr Mladek To: Andy Shevchenko , Sergey Senozhatsky , Steven Rostedt Cc: Rasmus Villemoes , Sergey Senozhatsky , linux-kernel@vger.kernel.org, =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Ilya Dryomov , Kees Cook , "Tobin C . Harding" , Petr Mladek Subject: [PATCH 1/3] lib/test_printf: Clean up test of hashed pointers Date: Thu, 27 Feb 2020 14:01:21 +0100 Message-Id: <20200227130123.32442-2-pmladek@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20200227130123.32442-1-pmladek@suse.com> References: <20200227130123.32442-1-pmladek@suse.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The commit ad67b74d2469d9b82a ("printk: hash addresses printed with %p") helps to prevent leaking kernel addresses. The testing of this functionality is a bit problematic because the output depends on a random key that is generated during boot. Though, it is still possible to check some aspects: + output string length + hash differs from the original pointer value + top half bits are zeroed on 64-bit systems This is currently done by a maze of functions: + It is hard to follow. + Some code is duplicated, e.g. the check for initialized crng. + The zeroed top half bits are tested only with one hardcoded PTR. + plain() increments "failed_tests" but not "total_tests". + The generic test_hashed() does not touch number of tests at all. Move all the checks into test_hashed() so that they are done for any given pointer that should get hashed. Also handle test counters and internal errors the same way as the existing test() function. Signed-off-by: Petr Mladek --- lib/test_printf.c | 130 ++++++++++++++++++------------------------------------ 1 file changed, 42 insertions(+), 88 deletions(-) diff --git a/lib/test_printf.c b/lib/test_printf.c index 2d9f520d2f27..6fa6fb606554 100644 --- a/lib/test_printf.c +++ b/lib/test_printf.c @@ -215,29 +215,6 @@ test_string(void) #define PTR_VAL_NO_CRNG "(____ptrval____)" #define ZEROS "00000000" /* hex 32 zero bits */ -static int __init -plain_format(void) -{ - char buf[PLAIN_BUF_SIZE]; - int nchars; - - nchars = snprintf(buf, PLAIN_BUF_SIZE, "%p", PTR); - - if (nchars != PTR_WIDTH) - return -1; - - if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { - pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"", - PTR_VAL_NO_CRNG); - return 0; - } - - if (strncmp(buf, ZEROS, strlen(ZEROS)) != 0) - return -1; - - return 0; -} - #else #define PTR_WIDTH 8 @@ -246,88 +223,65 @@ plain_format(void) #define PTR_VAL_NO_CRNG "(ptrval)" #define ZEROS "" -static int __init -plain_format(void) -{ - /* Format is implicitly tested for 32 bit machines by plain_hash() */ - return 0; -} - #endif /* BITS_PER_LONG == 64 */ -static int __init -plain_hash_to_buffer(const void *p, char *buf, size_t len) +static void __init +test_hashed(const char *fmt, const void *p) { + char real[PLAIN_BUF_SIZE]; + char hash[PLAIN_BUF_SIZE]; int nchars; - nchars = snprintf(buf, len, "%p", p); - - if (nchars != PTR_WIDTH) - return -1; + total_tests++; - if (strncmp(buf, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { - pr_warn("crng possibly not yet initialized. plain 'p' buffer contains \"%s\"", - PTR_VAL_NO_CRNG); - return 0; + nchars = snprintf(real, sizeof(real), "%px", p); + if (nchars != PTR_WIDTH) { + pr_err("error in test suite: vsprintf(\"%%px\", p) returned number of characters %d, expected %d\n", + nchars, PTR_WIDTH); + goto err; } - return 0; -} - -static int __init -plain_hash(void) -{ - char buf[PLAIN_BUF_SIZE]; - int ret; - - ret = plain_hash_to_buffer(PTR, buf, PLAIN_BUF_SIZE); - if (ret) - return ret; - - if (strncmp(buf, PTR_STR, PTR_WIDTH) == 0) - return -1; - - return 0; -} - -/* - * We can't use test() to test %p because we don't know what output to expect - * after an address is hashed. - */ -static void __init -plain(void) -{ - int err; + nchars = snprintf(hash, sizeof(hash), fmt, p); + if (nchars != PTR_WIDTH) { + pr_warn("vsprintf(\"%s\", p) returned number of characters %d, expected %d\n", + fmt, nchars, PTR_WIDTH); + goto err; + } - err = plain_hash(); - if (err) { - pr_warn("plain 'p' does not appear to be hashed\n"); - failed_tests++; + if (strncmp(hash, PTR_VAL_NO_CRNG, PTR_WIDTH) == 0) { + pr_warn_once("crng possibly not yet initialized. vsprinf(\"%s\", p) printed \"%s\"", + fmt, hash); + total_tests--; return; } - err = plain_format(); - if (err) { - pr_warn("hashing plain 'p' has unexpected format\n"); - failed_tests++; + /* + * There is a small chance of a false negative on 32-bit systems + * when the hash is the same as the pointer value. + */ + if (strncmp(hash, real, PTR_WIDTH) == 0) { + pr_warn("vsprintf(\"%s\", p) returned %s, expected hashed pointer\n", + fmt, hash); + goto err; + } + +#if BITS_PER_LONG == 64 + if (strncmp(hash, ZEROS, PTR_WIDTH / 2) != 0) { + pr_warn("vsprintf(\"%s\", p) returned %s, expected %s in the top half bits\n", + fmt, hash, ZEROS); + goto err; } +#endif + return; + +err: + failed_tests++; } static void __init -test_hashed(const char *fmt, const void *p) +plain(void) { - char buf[PLAIN_BUF_SIZE]; - int ret; - - /* - * No need to increase failed test counter since this is assumed - * to be called after plain(). - */ - ret = plain_hash_to_buffer(p, buf, PLAIN_BUF_SIZE); - if (ret) - return; - - test(buf, fmt, p); + test_hashed("%p", PTR); } static void __init -- 2.16.4