Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp9043481pxu; Mon, 28 Dec 2020 05:15:13 -0800 (PST) X-Google-Smtp-Source: ABdhPJx5NpekXL5FmNlkhWAqN/9z9lQrRo4Qe+t27OlM05BQFKgeYNXTdkd53NDZEx2yMg2UIiMa X-Received: by 2002:aa7:c698:: with SMTP id n24mr42091653edq.277.1609161312826; Mon, 28 Dec 2020 05:15:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609161312; cv=none; d=google.com; s=arc-20160816; b=uoqonVI0RWjFGtmmRtzReE4oyg/jUkQgjJJ7OOxHkcJH79RefDDwRxDTGldOZIfpie HnCPlSyy3w4kxZX6xYpbCaE4tFvbTDEZJIITV3Obc02nLoNaibZoWg+Hp5w1S+5ntnDr OF0sxVi1oPqfByWqjjUYKgH5fS4Ad9uEKsQkKqHGeeJh6WB88TxI4PAX8bS5t1Ll0gHT t7W5CDWWzA3zCBYTwMNvmuci6wm5KjjDFcKJrxR938nMUXVO204b0dtwGXcdfp/Mjybf cui9FqehshFxWMr9CRLuHN+3iDjk2ksDu3qJtM8kVk+eoMortKqyioFZu17CmWN+Ge0E Sesg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=W98HpHGIUMMNBMva8LfkW2qEgz++H/cmqD9sl5T/He0=; b=g0gdtayUiKLRWoHS406188vJZV7C6DhT1zvz8RgsP5TudphEDrTkFsGlJi7BCXm5CU vGGufizqJB1RxRROlusaiJugE9aZh37R9eRKUOf0BDVwR4fV8Z2U/oJphHEhDDIkaWy+ Zmod1HYAxyppvi3tJxlVhC5C2M/QoS+HPVJrQO8SuUK3JwttQiob11vdVxhZoU6bKnQB pB2rr9KRg00FL5jWD2M7iPz1+o73EACGulqbk+l6dCGcrac96LyKNce+Fv7lmp8mRNNQ Hd8pTY/tRS1ung7TTHgQMuD+xs5+Ek4/78R6M0JwbE0vUEjaIq8UbXppCmgHQZzOw6qK 2dXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=2UvBD1Pd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mf27si18215531ejb.129.2020.12.28.05.14.50; Mon, 28 Dec 2020 05:15:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=2UvBD1Pd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731404AbgL1NKa (ORCPT + 99 others); Mon, 28 Dec 2020 08:10:30 -0500 Received: from mail.kernel.org ([198.145.29.99]:38274 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731359AbgL1NK3 (ORCPT ); Mon, 28 Dec 2020 08:10:29 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 079F422AAD; Mon, 28 Dec 2020 13:09:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609160988; bh=x7wPcdaHSJvPn+6YXf9F4WM7LGOJSdklufUles/136E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=2UvBD1Pd2kZe5WrdmeMba7WcPiBpOHvVErtnnyQmT3XRZfU3m7rOQemBwtPwa+j5h z5CEDBchD0vODHRWxNj5PCmXs/j56w55Ub0ymkuiNKe0RGUP+wjx345/Tx/qAf9YPt ozaaTzGX0J5mZB1JN6gZE/S9/GV1uUlfO5VolTCQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+92ead4eb8e26a26d465e@syzkaller.appspotmail.com, Eric Biggers , Herbert Xu Subject: [PATCH 4.14 062/242] crypto: af_alg - avoid undefined behavior accessing salg_name Date: Mon, 28 Dec 2020 13:47:47 +0100 Message-Id: <20201228124907.733528701@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201228124904.654293249@linuxfoundation.org> References: <20201228124904.654293249@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Biggers commit 92eb6c3060ebe3adf381fd9899451c5b047bb14d upstream. Commit 3f69cc60768b ("crypto: af_alg - Allow arbitrarily long algorithm names") made the kernel start accepting arbitrarily long algorithm names in sockaddr_alg. However, the actual length of the salg_name field stayed at the original 64 bytes. This is broken because the kernel can access indices >= 64 in salg_name, which is undefined behavior -- even though the memory that is accessed is still located within the sockaddr structure. It would only be defined behavior if the array were properly marked as arbitrary-length (either by making it a flexible array, which is the recommended way these days, or by making it an array of length 0 or 1). We can't simply change salg_name into a flexible array, since that would break source compatibility with userspace programs that embed sockaddr_alg into another struct, or (more commonly) declare a sockaddr_alg like 'struct sockaddr_alg sa = { .salg_name = "foo" };'. One solution would be to change salg_name into a flexible array only when '#ifdef __KERNEL__'. However, that would keep userspace without an easy way to actually use the longer algorithm names. Instead, add a new structure 'sockaddr_alg_new' that has the flexible array field, and expose it to both userspace and the kernel. Make the kernel use it correctly in alg_bind(). This addresses the syzbot report "UBSAN: array-index-out-of-bounds in alg_bind" (https://syzkaller.appspot.com/bug?extid=92ead4eb8e26a26d465e). Reported-by: syzbot+92ead4eb8e26a26d465e@syzkaller.appspotmail.com Fixes: 3f69cc60768b ("crypto: af_alg - Allow arbitrarily long algorithm names") Cc: # v4.12+ Signed-off-by: Eric Biggers Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- crypto/af_alg.c | 10 +++++++--- include/uapi/linux/if_alg.h | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -151,7 +151,7 @@ static int alg_bind(struct socket *sock, const u32 allowed = CRYPTO_ALG_KERN_DRIVER_ONLY; struct sock *sk = sock->sk; struct alg_sock *ask = alg_sk(sk); - struct sockaddr_alg *sa = (void *)uaddr; + struct sockaddr_alg_new *sa = (void *)uaddr; const struct af_alg_type *type; void *private; int err; @@ -159,7 +159,11 @@ static int alg_bind(struct socket *sock, if (sock->state == SS_CONNECTED) return -EINVAL; - if (addr_len < sizeof(*sa)) + BUILD_BUG_ON(offsetof(struct sockaddr_alg_new, salg_name) != + offsetof(struct sockaddr_alg, salg_name)); + BUILD_BUG_ON(offsetof(struct sockaddr_alg, salg_name) != sizeof(*sa)); + + if (addr_len < sizeof(*sa) + 1) return -EINVAL; /* If caller uses non-allowed flag, return error. */ @@ -167,7 +171,7 @@ static int alg_bind(struct socket *sock, return -EINVAL; sa->salg_type[sizeof(sa->salg_type) - 1] = 0; - sa->salg_name[sizeof(sa->salg_name) + addr_len - sizeof(*sa) - 1] = 0; + sa->salg_name[addr_len - sizeof(*sa) - 1] = 0; type = alg_get_type(sa->salg_type); if (IS_ERR(type) && PTR_ERR(type) == -ENOENT) { --- a/include/uapi/linux/if_alg.h +++ b/include/uapi/linux/if_alg.h @@ -24,6 +24,22 @@ struct sockaddr_alg { __u8 salg_name[64]; }; +/* + * Linux v4.12 and later removed the 64-byte limit on salg_name[]; it's now an + * arbitrary-length field. We had to keep the original struct above for source + * compatibility with existing userspace programs, though. Use the new struct + * below if support for very long algorithm names is needed. To do this, + * allocate 'sizeof(struct sockaddr_alg_new) + strlen(algname) + 1' bytes, and + * copy algname (including the null terminator) into salg_name. + */ +struct sockaddr_alg_new { + __u16 salg_family; + __u8 salg_type[14]; + __u32 salg_feat; + __u32 salg_mask; + __u8 salg_name[]; +}; + struct af_alg_iv { __u32 ivlen; __u8 iv[0];