From patchwork Tue Mar 22 12:12:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolai Stange X-Patchwork-Id: 8641711 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Original-To: patchwork-linux-crypto@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A08D89F294 for ; Tue, 22 Mar 2016 12:14:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9839D202FE for ; Tue, 22 Mar 2016 12:14:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9A96C2037F for ; Tue, 22 Mar 2016 12:14:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758359AbcCVMOJ (ORCPT ); Tue, 22 Mar 2016 08:14:09 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:36833 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756757AbcCVMOB (ORCPT ); Tue, 22 Mar 2016 08:14:01 -0400 Received: by mail-wm0-f68.google.com with SMTP id l68so29152750wml.3; Tue, 22 Mar 2016 05:14:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7SnTkrkZAOhVOO9r8XSGdEcKLvb46V1s3UJ5jWtSbLs=; b=vE9t00Nq+xKfrY/Q7o9cH10mKYUCxnmqw6dYCtpsmzJK1Yp2P5f1B/hUV/VfJyNkyd yrDgcWSS7nKx7SjfgBy849VY+eRPtzay/wTTz7rN1EsuV5gOeIIg01+rNUgrZj7eBf9z kswcFrISF4WotIztVOCx9ObGf35WQXBWgTqGF1RRvHVW/Yd+EGAjAA+iVF3rStwYfvEy 8gmwfc7Iv4yOdlsCQ0mqBqcEBa5X5NahUp3gP/CCwrRCkuQJd2uHu0swlMw3cP9qs/k5 6RazJdIDoc9MNEansooUX2sCyTTMy1kZyEgLpuHGWM7f/umD/JW0ZqOHPErIA000PAeB Vz1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7SnTkrkZAOhVOO9r8XSGdEcKLvb46V1s3UJ5jWtSbLs=; b=Lb5ccXwsqfXRkvBi286Pp68hXrZN6s1KU07Lxd8FoY5Be53lCKHj4RRcy3Ygzlbdo1 /X8ztyKBZHPsj0CLYCo5CXqEZzz4IwIftb/Yy7+cNDItyIAELh+aAWKqKS2CrQl3gsqu a/fFg/KaOsdwnxTSUM2HLQEo8849QFOJkp6GN5EVLbxnm+HRlRLqvVhqA+d0i8EQvASD 3gXFebBDPuQPBETYuWgumOhG4auu53lPvMm9vPEpwBrFRs8dBDXcP4jRlpXNDA9g8zRb 69asin//HG65AmTx9lXzgqgzkxEGqy7GFGxNzejKMCD+TdkqD1dScyssKeY49dA54QzM ROug== X-Gm-Message-State: AD7BkJJJ8q1Naln6F/nZGctnHS4GleD3Rlgg7QlCng5DQKSeTepRCMYsbEyQXyT4fDPtzA== X-Received: by 10.194.222.234 with SMTP id qp10mr35894473wjc.138.1458648839795; Tue, 22 Mar 2016 05:13:59 -0700 (PDT) Received: from localhost (x55b18fc0.dyn.telefonica.de. [85.177.143.192]) by smtp.gmail.com with ESMTPSA id j10sm29928317wjb.46.2016.03.22.05.13.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Mar 2016 05:13:59 -0700 (PDT) From: Nicolai Stange To: Herbert Xu , "David S. Miller" Cc: Tadeusz Struk , Michal Marek , Andrzej Zaborowski , Stephan Mueller , Arnd Bergmann , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Nicolai Stange Subject: [PATCH v3 04/14] lib/mpi: mpi_write_sgl(): fix out-of-bounds stack access Date: Tue, 22 Mar 2016 13:12:38 +0100 Message-Id: <1458648768-1469-5-git-send-email-nicstange@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1458648768-1469-1-git-send-email-nicstange@gmail.com> References: <1458648768-1469-1-git-send-email-nicstange@gmail.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Within the copying loop in mpi_write_sgl(), we have if (lzeros) { mpi_limb_t *limb1 = (void *)p - sizeof(alimb); mpi_limb_t *limb2 = (void *)p - sizeof(alimb) + lzeros; *limb1 = *limb2; ... } where p points past the end of alimb2 which lives on the stack and contains the current limb in BE order. The purpose of the above is to shift the non-zero bytes of alimb2 to its beginning in memory, i.e. to skip its leading zero bytes. However, limb2 points somewhere into the middle of alimb2 and thus, reading *limb2 pulls in lzero bytes from somewhere. Indeed, KASAN splats: BUG: KASAN: stack-out-of-bounds in mpi_write_to_sgl+0x4e3/0x6f0 at addr ffff8800cb04f601 Read of size 8 by task systemd-udevd/391 page:ffffea00032c13c0 count:0 mapcount:0 mapping: (null) index:0x0 flags: 0x3fff8000000000() page dumped because: kasan: bad access detected CPU: 3 PID: 391 Comm: systemd-udevd Tainted: G B L 4.5.0-next-20160316+ #12 [...] Call Trace: [] dump_stack+0xdc/0x15e [] ? _atomic_dec_and_lock+0xa2/0xa2 [] ? __dump_page+0x185/0x330 [] kasan_report_error+0x5e6/0x8b0 [] ? kzfree+0x2d/0x40 [] ? mpi_free_limb_space+0xe/0x20 [] ? mpi_powm+0x37e/0x16f0 [] kasan_report+0x71/0xa0 [] ? mpi_write_to_sgl+0x4e3/0x6f0 [] __asan_load8+0x64/0x70 [] mpi_write_to_sgl+0x4e3/0x6f0 [] ? mpi_set_buffer+0x620/0x620 [] ? mpi_cmp+0xbf/0x180 [] rsa_verify+0x202/0x260 What's more, since lzeros can be anything from 1 to sizeof(mpi_limb_t)-1, the above will cause unaligned accesses which is bad on non-x86 archs. Fix the issue, by preparing the starting point p for the upcoming copy operation instead of shifting the source memory, i.e. alimb2. Fixes: 2d4d1eea540b ("lib/mpi: Add mpi sgl helpers") Signed-off-by: Nicolai Stange --- lib/mpi/mpicoder.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c index 78ec4e1..b05d390 100644 --- a/lib/mpi/mpicoder.c +++ b/lib/mpi/mpicoder.c @@ -403,15 +403,11 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes, #error please implement for this limb size. #endif if (lzeros) { - mpi_limb_t *limb1 = (void *)p - sizeof(alimb); - mpi_limb_t *limb2 = (void *)p - sizeof(alimb) - + lzeros; - *limb1 = *limb2; y = lzeros; lzeros = 0; } - p = p - sizeof(alimb); + p = p - sizeof(alimb) + y; for (x = 0; x < sizeof(alimb) - y; x++) { if (!buf_len) {