From patchwork Mon Aug 19 07:36:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Po-Hsu Lin X-Patchwork-Id: 1149068 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Bm3F5QtFz9sNF; Mon, 19 Aug 2019 17:37:13 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1hzcE1-0003A1-J9; Mon, 19 Aug 2019 07:37:09 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1hzcE0-00039O-5l for kernel-team@lists.ubuntu.com; Mon, 19 Aug 2019 07:37:08 +0000 Received: from mail-pl1-f197.google.com ([209.85.214.197]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1hzcDz-0001ck-Lt for kernel-team@lists.ubuntu.com; Mon, 19 Aug 2019 07:37:07 +0000 Received: by mail-pl1-f197.google.com with SMTP id y22so1535641plr.20 for ; Mon, 19 Aug 2019 00:37:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=+h3J1uTiNpflYYNr4osOO5d3xhFZ0ddCDfzbsEnAKOw=; b=lQp+OuI0Fu6bfhA8sbpObgTPlnkel4LvXpLjrLp5JmVDeilN2f+Ly9YkEepnE+QiVn KglA/W4bRiPk+3nowr5Y4Rv8o56j/MJC6+bNZm/0t4j6l4rvdmezgXlGN5npAhDt+Bfm gybTL7IoueFuw+7ja8ExzOQTBmcpOiyEL+stfl9WKCBRWKdoqF8xpeuQyYPo02t8nIlT V6EUjiGIZIiLFow30GDLQXcDu2gh0f2t9nERZyVYmCmrR/DtQg/cDfwrkSIRszAOs7BR Vq4qyfr5mSe2n/cO61nIGqJvnrxLpoWq++6QqtSBHy29NfPTrfY6Lk/ZZF/a3MPqjT/3 u3cg== X-Gm-Message-State: APjAAAXDMXLYAgvzG95eqt0ynKwYUPSA4dGeXyIf7ofboU0/jpjlz9gI bog1QXhWehnG2XegPml/Z4zYUE5k8wwyqOQfgirVIjleDutcgrxvn4UmE2nKsiJwU3FLJV3kAZR UhxujIIxrY6v3HFQEIROrD8htkKpDgctatq6ziOWe X-Received: by 2002:a17:90a:c403:: with SMTP id i3mr18653293pjt.110.1566200226138; Mon, 19 Aug 2019 00:37:06 -0700 (PDT) X-Google-Smtp-Source: APXvYqwawYGWVTcxBUVh5pJahq0WivRfwDu68j2atbh2tOGCAhmevhOnDpWWOtoNzYESFXRVddUkMQ== X-Received: by 2002:a17:90a:c403:: with SMTP id i3mr18653285pjt.110.1566200225894; Mon, 19 Aug 2019 00:37:05 -0700 (PDT) Received: from Leggiero.taipei.internal (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id l4sm14466063pff.50.2019.08.19.00.37.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2019 00:37:05 -0700 (PDT) From: Po-Hsu Lin To: kernel-team@lists.ubuntu.com Subject: [B/linux-aws][SRU][PATCH 1/1] crypto: authenc - fix parsing key with misaligned rta_len Date: Mon, 19 Aug 2019 15:36:57 +0800 Message-Id: <20190819073657.14086-2-po-hsu.lin@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190819073657.14086-1-po-hsu.lin@canonical.com> References: <20190819073657.14086-1-po-hsu.lin@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Eric Biggers BugLink: https://bugs.launchpad.net/bugs/1829725 Keys for "authenc" AEADs are formatted as an rtattr containing a 4-byte 'enckeylen', followed by an authentication key and an encryption key. crypto_authenc_extractkeys() parses the key to find the inner keys. However, it fails to consider the case where the rtattr's payload is longer than 4 bytes but not 4-byte aligned, and where the key ends before the next 4-byte aligned boundary. In this case, 'keylen -= RTA_ALIGN(rta->rta_len);' underflows to a value near UINT_MAX. This causes a buffer overread and crash during crypto_ahash_setkey(). Fix it by restricting the rtattr payload to the expected size. Reproducer using AF_ALG: #include #include #include int main() { int fd; struct sockaddr_alg addr = { .salg_type = "aead", .salg_name = "authenc(hmac(sha256),cbc(aes))", }; struct { struct rtattr attr; __be32 enckeylen; char keys[1]; } __attribute__((packed)) key = { .attr.rta_len = sizeof(key), .attr.rta_type = 1 /* CRYPTO_AUTHENC_KEYA_PARAM */, }; fd = socket(AF_ALG, SOCK_SEQPACKET, 0); bind(fd, (void *)&addr, sizeof(addr)); setsockopt(fd, SOL_ALG, ALG_SET_KEY, &key, sizeof(key)); } It caused: BUG: unable to handle kernel paging request at ffff88007ffdc000 PGD 2e01067 P4D 2e01067 PUD 2e04067 PMD 2e05067 PTE 0 Oops: 0000 [#1] SMP CPU: 0 PID: 883 Comm: authenc Not tainted 4.20.0-rc1-00108-g00c9fe37a7f27 #13 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-20181126_142135-anatol 04/01/2014 RIP: 0010:sha256_ni_transform+0xb3/0x330 arch/x86/crypto/sha256_ni_asm.S:155 [...] Call Trace: sha256_ni_finup+0x10/0x20 arch/x86/crypto/sha256_ssse3_glue.c:321 crypto_shash_finup+0x1a/0x30 crypto/shash.c:178 shash_digest_unaligned+0x45/0x60 crypto/shash.c:186 crypto_shash_digest+0x24/0x40 crypto/shash.c:202 hmac_setkey+0x135/0x1e0 crypto/hmac.c:66 crypto_shash_setkey+0x2b/0xb0 crypto/shash.c:66 shash_async_setkey+0x10/0x20 crypto/shash.c:223 crypto_ahash_setkey+0x2d/0xa0 crypto/ahash.c:202 crypto_authenc_setkey+0x68/0x100 crypto/authenc.c:96 crypto_aead_setkey+0x2a/0xc0 crypto/aead.c:62 aead_setkey+0xc/0x10 crypto/algif_aead.c:526 alg_setkey crypto/af_alg.c:223 [inline] alg_setsockopt+0xfe/0x130 crypto/af_alg.c:256 __sys_setsockopt+0x6d/0xd0 net/socket.c:1902 __do_sys_setsockopt net/socket.c:1913 [inline] __se_sys_setsockopt net/socket.c:1910 [inline] __x64_sys_setsockopt+0x1f/0x30 net/socket.c:1910 do_syscall_64+0x4a/0x180 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe Fixes: e236d4a89a2f ("[CRYPTO] authenc: Move enckeylen into key itself") Cc: # v2.6.25+ Signed-off-by: Eric Biggers Signed-off-by: Herbert Xu (cherry picked from commit 8f9c469348487844328e162db57112f7d347c49f) Signed-off-by: Po-Hsu Lin --- crypto/authenc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/crypto/authenc.c b/crypto/authenc.c index 0db344d..053287d 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -58,14 +58,22 @@ int crypto_authenc_extractkeys(struct crypto_authenc_keys *keys, const u8 *key, return -EINVAL; if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) return -EINVAL; - if (RTA_PAYLOAD(rta) < sizeof(*param)) + + /* + * RTA_OK() didn't align the rtattr's payload when validating that it + * fits in the buffer. Yet, the keys should start on the next 4-byte + * aligned boundary. To avoid confusion, require that the rtattr + * payload be exactly the param struct, which has a 4-byte aligned size. + */ + if (RTA_PAYLOAD(rta) != sizeof(*param)) return -EINVAL; + BUILD_BUG_ON(sizeof(*param) % RTA_ALIGNTO); param = RTA_DATA(rta); keys->enckeylen = be32_to_cpu(param->enckeylen); - key += RTA_ALIGN(rta->rta_len); - keylen -= RTA_ALIGN(rta->rta_len); + key += rta->rta_len; + keylen -= rta->rta_len; if (keylen < keys->enckeylen) return -EINVAL;