Received: by 2002:a05:6512:2355:0:0:0:0 with SMTP id p21csp213683lfu; Wed, 30 Mar 2022 21:16:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzMaBFeBRl0AGUFMmVhbNLO3kmx+csJTVV8Am+iH/TFyxPpdt2AItdoMPjj9MREkVLX+sNz X-Received: by 2002:a62:cd83:0:b0:4fa:7410:6d86 with SMTP id o125-20020a62cd83000000b004fa74106d86mr37568347pfg.52.1648700187697; Wed, 30 Mar 2022 21:16:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648700187; cv=none; d=google.com; s=arc-20160816; b=lncfJmdKQMtVAvyep6qWj9raEuekyx5dV1+Q8BiTRWIMaAUKTgr48rC4RJuowM4NgV DIinXLciZhFIkENLVFnPpzwvz6s2cN0MiUs/pda4d2RY94rEQ84fc7kTMJ3v2rg94Re6 EKMDvNPxJiPlVrBnxmFlZpYOB9il2LmHt/s3c2UjZ8nmLHkzEh/6SvXFdL7P2pUKdnKF L7Re83iHIsqAWKhTFlaweVZA2VWyF5TZHqKIBYJOjGHidIdcRq6W622qamQGo8dWt/f5 jJjGRVqyEJNpjJ206S5/KqqUCzxtBclPbdLv5uaXGZsoXGxpvcDVbj+vUMVx/e6mBWSJ t9dw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=g1AWkbjotYcH8pbymQNDkHahrYhzMDnkh9MdYAVn3/c=; b=JCVyrmTQt+puRQZl6gCFGasmgFQtZ/Llyd+qh+QueirbvpuRuTw+Jcw9x6BS4AOjAm nvNIRlh3ihgDrjJuTiJccYDCM+yjJQP/tJZnCXh+N6I3uTWAMl/APoZgo7pMPBOFGIbW xKvepINdVxz30vtcKgSjnpBUpcUUaWC5mNjFyfS5N8kpGmKE0dVDa2BTpMAEFLLaa4oO V9Rkiw/eZfwA+7Whr3qanq7cJ6dul1hPSkEvVHoEoENFW54ZD31e6WL3ea4SGd2RSSvc CG7S3D4uZy8M/vedbhkvsyDT5f3NAas1CEMkyZ2PIO2zh+iL08l2Qa22PJhEsdi+60ZF Kx3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=YVms58oe; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id d33-20020a631d61000000b003816043f061si23566378pgm.598.2022.03.30.21.16.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Mar 2022 21:16:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=YVms58oe; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8E60A1DFDC7; Wed, 30 Mar 2022 20:26:00 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351336AbiC3VqK (ORCPT + 99 others); Wed, 30 Mar 2022 17:46:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351321AbiC3VqD (ORCPT ); Wed, 30 Mar 2022 17:46:03 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B69F2B859; Wed, 30 Mar 2022 14:44:17 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 55FB76171B; Wed, 30 Mar 2022 21:44:17 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB0C3C34110; Wed, 30 Mar 2022 21:44:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1648676656; bh=aM5mAmK19Mmcbly0+Z8gAQpXnfdX++fFzWKDjWvJamA=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=YVms58oeRQIRHD+lDm8U3Fj7oDVn8CVdEfQPPGYYU+ckHpeztbY2KwDnPChZouShA 2qLDA3HcY9KngfFQeVSIStt+7fG6GyMlkiQ5zTZQnxd6Qz8VBToY3c4djMrxe1iT9F 84ts3qlMLatnOyh6sIy2p5sw2Gx1OwEylvyL58V31YurGyAvQDv2lPqkHQKhUq0qjZ QCyVRCxfPd8ZMprBCTrST0fL2EzWA2yxY0uVCzsY9Uim5UZDyhydAie2C828cDibAi laIZnPzNWtUUpZs6TQx5DogiLpNC/QRLykiIK5ro96lAlN0B7CbkIcxuRLEu69IGyr x61KZ7RCmF8sw== Received: by mail-oi1-f181.google.com with SMTP id e189so23436624oia.8; Wed, 30 Mar 2022 14:44:16 -0700 (PDT) X-Gm-Message-State: AOAM533wVN7wmNRoHfg6/dKEvqY6REE5GwjdkxuOq9qhkn6M/kj54RCF jZDtezAloHi5gPNyb9tzIHLGYskvDcuOb1juIZQ= X-Received: by 2002:aca:674c:0:b0:2d9:c460:707c with SMTP id b12-20020aca674c000000b002d9c460707cmr1139478oiy.126.1648676655872; Wed, 30 Mar 2022 14:44:15 -0700 (PDT) MIME-Version: 1.0 References: <20220330085009.1011614-1-william.xuanziyang@huawei.com> <20220330093925.2d8ee6ca@kernel.org> <20220330132406.633c2da8@kernel.org> In-Reply-To: <20220330132406.633c2da8@kernel.org> From: Ard Biesheuvel Date: Wed, 30 Mar 2022 23:44:04 +0200 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH net] net/tls: fix slab-out-of-bounds bug in decrypt_internal To: Jakub Kicinski Cc: Eric Biggers , Herbert Xu , Ziyang Xuan , borisp@nvidia.com, John Fastabend , Daniel Borkmann , "David S. Miller" , Paolo Abeni , "open list:BPF JIT for MIPS (32-BIT AND 64-BIT)" , vakul.garg@nxp.com, davejwatson@fb.com, Linux Kernel Mailing List , Vadim Fedorenko , Linux Crypto Mailing List Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org On Wed, 30 Mar 2022 at 22:24, Jakub Kicinski wrote: > > On Wed, 30 Mar 2022 09:39:25 -0700 Jakub Kicinski wrote: > > On Wed, 30 Mar 2022 16:50:09 +0800 Ziyang Xuan wrote: > > > The memory size of tls_ctx->rx.iv for AES128-CCM is 12 setting in > > > tls_set_sw_offload(). The return value of crypto_aead_ivsize() > > > for "ccm(aes)" is 16. So memcpy() require 16 bytes from 12 bytes > > > memory space will trigger slab-out-of-bounds bug as following: > > > > > > ================================================================== > > > BUG: KASAN: slab-out-of-bounds in decrypt_internal+0x385/0xc40 [tls] > > > Read of size 16 at addr ffff888114e84e60 by task tls/10911 > > > > > > Call Trace: > > > > > > dump_stack_lvl+0x34/0x44 > > > print_report.cold+0x5e/0x5db > > > ? decrypt_internal+0x385/0xc40 [tls] > > > kasan_report+0xab/0x120 > > > ? decrypt_internal+0x385/0xc40 [tls] > > > kasan_check_range+0xf9/0x1e0 > > > memcpy+0x20/0x60 > > > decrypt_internal+0x385/0xc40 [tls] > > > ? tls_get_rec+0x2e0/0x2e0 [tls] > > > ? process_rx_list+0x1a5/0x420 [tls] > > > ? tls_setup_from_iter.constprop.0+0x2e0/0x2e0 [tls] > > > decrypt_skb_update+0x9d/0x400 [tls] > > > tls_sw_recvmsg+0x3c8/0xb50 [tls] > > > > > > Allocated by task 10911: > > > kasan_save_stack+0x1e/0x40 > > > __kasan_kmalloc+0x81/0xa0 > > > tls_set_sw_offload+0x2eb/0xa20 [tls] > > > tls_setsockopt+0x68c/0x700 [tls] > > > __sys_setsockopt+0xfe/0x1b0 > > > > Interesting, are you running on non-x86 platform or with some crypto > > accelerator? I wonder why we're not hitting it with KASAN and the > > selftest we have. > > I take that back, I can repro on x86 and 5.17, not sure why we're only > discovering this now. > > Noob question for crypto folks, ivsize for AES CCM is reported > as 16, but the real nonce size is 13 for TLS (q == 2, n == 13 > using NIST's variable names AFAICT). Are we required to zero out > the rest of the buffer? > Looking at crypto/ccm.c and the arm64 accelerated implementation, it appears the driver takes care of this: the first byte of the IV (q in your example, but L in the crypto code) is the number of bytes minus one that will be used for the counter, which starts at 0x1 for the CTR cipher stream generation but is reset to 0x0 to encrypt the authentication tag. Both drivers do a memset() to zero the last q+1 bytes of the IV. > In particular I think I've seen transient crypto failures with > SM4 CCM in the past and zeroing the tail of the iv buffer seems > to make the tests pass reliably. > Yes, that seems like a bug, although there is only a single implementation of the combined SM4-CCM transform in the tree, and generic SM4 in C would be combined with the CCM chaining mode driver, which is also used for generic AES. > > > Reserve MAX_IV_SIZE memory space for iv to be compatible with all > > > ciphers. And do iv and salt copy like done in tls_do_encryption(). > > > > > > Fixes: f295b3ae9f59 ("net/tls: Add support of AES128-CCM based ciphers") > > > Signed-off-by: Ziyang Xuan > > > --- > > > net/tls/tls_sw.c | 10 +++------- > > > 1 file changed, 3 insertions(+), 7 deletions(-) > > > > > > diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c > > > index 0024a692f0f8..6b858f995b23 100644 > > > --- a/net/tls/tls_sw.c > > > +++ b/net/tls/tls_sw.c > > > @@ -1456,7 +1456,7 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb, > > > aead_size = sizeof(*aead_req) + crypto_aead_reqsize(ctx->aead_recv); > > > mem_size = aead_size + (nsg * sizeof(struct scatterlist)); > > > mem_size = mem_size + prot->aad_size; > > > - mem_size = mem_size + crypto_aead_ivsize(ctx->aead_recv); > > > + mem_size = mem_size + MAX_IV_SIZE; > > > > This change is not strictly required for the patch, right? > > Can we drop it, and perhaps send as an optimization separately later? > > > > > /* Allocate a single block of memory which contains > > > * aead_req || sgin[] || sgout[] || aad || iv. > > > @@ -1493,12 +1493,8 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb, > > > kfree(mem); > > > return err; > > > } > > > - if (prot->version == TLS_1_3_VERSION || > > > - prot->cipher_type == TLS_CIPHER_CHACHA20_POLY1305) > > > - memcpy(iv + iv_offset, tls_ctx->rx.iv, > > > - crypto_aead_ivsize(ctx->aead_recv)); > > > - else > > > - memcpy(iv + iv_offset, tls_ctx->rx.iv, prot->salt_size); > > > + memcpy(iv + iv_offset, tls_ctx->rx.iv, > > > + prot->iv_size + prot->salt_size); > > > > If the IV really is 16B then we're passing 4 bytes of uninitialized > > data at the end of the buffer, right? > > > > > xor_iv_with_seq(prot, iv + iv_offset, tls_ctx->rx.rec_seq); > > FWIW this is the fix I tested: > > diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c > index 0024a692f0f8..dbc6bce01898 100644 > --- a/net/tls/tls_sw.c > +++ b/net/tls/tls_sw.c > @@ -1473,6 +1473,8 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb, > aad = (u8 *)(sgout + n_sgout); > iv = aad + prot->aad_size; > > + /* Prepare IV */ > + memset(iv, 0, crypto_aead_ivsize(ctx->aead_recv)); > /* For CCM based ciphers, first byte of nonce+iv is a constant */ > switch (prot->cipher_type) { > case TLS_CIPHER_AES_CCM_128: > @@ -1485,21 +1487,20 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb, > break; > } > > - /* Prepare IV */ > - err = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE, > - iv + iv_offset + prot->salt_size, > - prot->iv_size); > - if (err < 0) { > - kfree(mem); > - return err; > - } > if (prot->version == TLS_1_3_VERSION || > - prot->cipher_type == TLS_CIPHER_CHACHA20_POLY1305) > + prot->cipher_type == TLS_CIPHER_CHACHA20_POLY1305) { > memcpy(iv + iv_offset, tls_ctx->rx.iv, > - crypto_aead_ivsize(ctx->aead_recv)); > - else > + prot->iv_size + prot->salt_size); > + } else { > + err = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE, > + iv + iv_offset + prot->salt_size, > + prot->iv_size); > + if (err < 0) { > + kfree(mem); > + return err; > + } > memcpy(iv + iv_offset, tls_ctx->rx.iv, prot->salt_size); > - > + } > xor_iv_with_seq(prot, iv + iv_offset, tls_ctx->rx.rec_seq); > > /* Prepare AAD */ > -- > 2.34.1 > >