From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AF0BEC432C3 for ; Fri, 22 Nov 2019 06:01:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 87ADC20714 for ; Fri, 22 Nov 2019 06:01:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574402504; bh=kz+3hAKLZGXwy5NFQbtVkx/dpRrkzk30Gq1lot8iM1Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=z6jIO31xHxhwUVtvTprA58Ds6pBoICWzmJ7Jls5x+8ljwboQwcJBG67pHlSn71/ju tqk4DYfVuzvi50s0HRNXf1IN9dR/ILaewuJb7nROK4uI+UDlzcaia1LB8sTNmReT+G GmECukkH7Z6ayNzlfMAyXqRfuicg3w4gSkOkUO2Q= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728775AbfKVGBn (ORCPT ); Fri, 22 Nov 2019 01:01:43 -0500 Received: from mail.kernel.org ([198.145.29.99]:39918 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729024AbfKVGBm (ORCPT ); Fri, 22 Nov 2019 01:01:42 -0500 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 4E6122070E; Fri, 22 Nov 2019 06:01:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574402501; bh=kz+3hAKLZGXwy5NFQbtVkx/dpRrkzk30Gq1lot8iM1Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TW9ISkfeExVwgzrhbECzV3KB15/M9QaUY2yQ3uPZ1OLz3y8gRabCIdX1tes7jsxGh +1yt0qnSUDSgGyOWEmbuEBo0jAWF+1To3QNk3wMJVpX9BzfrbjBupg6nYZSQ6hSuKl u2ad+Soi3rYzzcjwJr+090oZJ0h5wQMT9juPB+kA= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Eric Biggers , Herbert Xu , Sasha Levin , linux-crypto@vger.kernel.org Subject: [PATCH AUTOSEL 4.9 11/91] crypto: user - support incremental algorithm dumps Date: Fri, 22 Nov 2019 01:00:09 -0500 Message-Id: <20191122060129.4239-10-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191122060129.4239-1-sashal@kernel.org> References: <20191122060129.4239-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org From: Eric Biggers [ Upstream commit 0ac6b8fb23c724b015d9ca70a89126e8d1563166 ] CRYPTO_MSG_GETALG in NLM_F_DUMP mode sometimes doesn't return all registered crypto algorithms, because it doesn't support incremental dumps. crypto_dump_report() only permits itself to be called once, yet the netlink subsystem allocates at most ~64 KiB for the skb being dumped to. Thus only the first recvmsg() returns data, and it may only include a subset of the crypto algorithms even if the user buffer passed to recvmsg() is large enough to hold all of them. Fix this by using one of the arguments in the netlink_callback structure to keep track of the current position in the algorithm list. Then userspace can do multiple recvmsg() on the socket after sending the dump request. This is the way netlink dumps work elsewhere in the kernel; it's unclear why this was different (probably just an oversight). Also fix an integer overflow when calculating the dump buffer size hint. Fixes: a38f7907b926 ("crypto: Add userspace configuration API") Signed-off-by: Eric Biggers Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- crypto/crypto_user.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index c90a1727cd2c6..60cf7d163731b 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -277,30 +277,33 @@ static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb) { - struct crypto_alg *alg; + const size_t start_pos = cb->args[0]; + size_t pos = 0; struct crypto_dump_info info; - int err; - - if (cb->args[0]) - goto out; - - cb->args[0] = 1; + struct crypto_alg *alg; + int res; info.in_skb = cb->skb; info.out_skb = skb; info.nlmsg_seq = cb->nlh->nlmsg_seq; info.nlmsg_flags = NLM_F_MULTI; + down_read(&crypto_alg_sem); list_for_each_entry(alg, &crypto_alg_list, cra_list) { - err = crypto_report_alg(alg, &info); - if (err) - goto out_err; + if (pos >= start_pos) { + res = crypto_report_alg(alg, &info); + if (res == -EMSGSIZE) + break; + if (res) + goto out; + } + pos++; } - + cb->args[0] = pos; + res = skb->len; out: - return skb->len; -out_err: - return err; + up_read(&crypto_alg_sem); + return res; } static int crypto_dump_report_done(struct netlink_callback *cb) @@ -483,7 +486,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && (nlh->nlmsg_flags & NLM_F_DUMP))) { struct crypto_alg *alg; - u16 dump_alloc = 0; + unsigned long dump_alloc = 0; if (link->dump == NULL) return -EINVAL; @@ -491,16 +494,16 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) down_read(&crypto_alg_sem); list_for_each_entry(alg, &crypto_alg_list, cra_list) dump_alloc += CRYPTO_REPORT_MAXSIZE; + up_read(&crypto_alg_sem); { struct netlink_dump_control c = { .dump = link->dump, .done = link->done, - .min_dump_alloc = dump_alloc, + .min_dump_alloc = min(dump_alloc, 65535UL), }; err = netlink_dump_start(crypto_nlsk, skb, nlh, &c); } - up_read(&crypto_alg_sem); return err; } -- 2.20.1