Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp9243622pxu; Mon, 28 Dec 2020 10:15:23 -0800 (PST) X-Google-Smtp-Source: ABdhPJyNw7e1A8oU/+6Qqg2U82uPopEO6OHgnkk/Nq4i+tMgeClJVjdC0Cz5bwMykM2N0E3Jfhtq X-Received: by 2002:a17:906:7f10:: with SMTP id d16mr42606149ejr.104.1609179323708; Mon, 28 Dec 2020 10:15:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609179323; cv=none; d=google.com; s=arc-20160816; b=FAX9qw8nRFsT+xOa4AkXLJxHom+DoeVo8Dp5UekGaR3FRmg5maWSUAGD0TOcNOsALx DMV/YscOlUqXXeLbH6wVy+hReLj8cZEDnZUPC37HIH9Pk6Z8HvrzidDm3MyalY45TYz4 Q6PvcuGJ9QJSh2zrnv75PUdesWMQm71tkux/uVc+45meC2wFo6XWV6gGAsVEDlo4EmLP 9o+PLqG1gQWv3GWuclm04qkRoCM5EZQyfW1vqan/eMKmNij3bHXBANmJHYRWvr4YeQAe s44ohGmq1MDkoY+w1rk9wqqH1qCxREtOkS+ujSrRXkruzzmWmUj/M0JSvhikS8vI9bI8 b4eQ== 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=ZrzrD89g8aYxd0Hsyn5je8fn1aPuBSEpGObb8EKIYEz4KOsDGZP2hlmQQZegt9fPdu wFcg8rlE/PQeXrR91vMe3BxMixDNFQupGcUKRZ22hhw/y+zHq3Ue2JeGzZ90sigBFjzW X1btzV06OIbLWYJI9FMJzOZS0zJFZFRoDDfRO9iv5GAgMQuyjzlW6JTJ+lXsdyDO3Poy xIlFF1aQRHtoznyxOz964cheGtOjY8kK58/35UN89NUHwHSNvpSs7DxpwT37hN4ca82Q jxkUprDugkS/I0qrufUtvBIKkp/UbX7N4X9yBRE4samtvkU2/kcUcdgJEC1zaguE1swh OVrQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=IZKzMbgL; 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 gl19si18866919ejb.476.2020.12.28.10.15.01; Mon, 28 Dec 2020 10:15:23 -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=IZKzMbgL; 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 S2389695AbgL1N1r (ORCPT + 99 others); Mon, 28 Dec 2020 08:27:47 -0500 Received: from mail.kernel.org ([198.145.29.99]:54636 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389035AbgL1NZw (ORCPT ); Mon, 28 Dec 2020 08:25:52 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 59C59207C9; Mon, 28 Dec 2020 13:25:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609161911; bh=x7wPcdaHSJvPn+6YXf9F4WM7LGOJSdklufUles/136E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IZKzMbgLT2bsqgl+Rtqoh2cgSVzAP6VFWj9DKM8MNbMgnHz43oZWehN32gogYSgb/ vkos5f29VUURrHSwQga01BRpLWbDB76NjTLBUQIk11aWCrd4YtFKArFiBFBrz1cpO/ yBPtGVRS1qFn18tKuQXCVCKtpWaLr+5dz3WFRGls= 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.19 094/346] crypto: af_alg - avoid undefined behavior accessing salg_name Date: Mon, 28 Dec 2020 13:46:53 +0100 Message-Id: <20201228124924.343770006@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201228124919.745526410@linuxfoundation.org> References: <20201228124919.745526410@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];