Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp13670970rwb; Sun, 27 Nov 2022 09:18:13 -0800 (PST) X-Google-Smtp-Source: AA0mqf7jA4Tq5Uy5DlOgQMLBlXxatgE2DBiks8tInCddvHYFkZF1OxmLcIGzsHOtUTti+zlYoQ54 X-Received: by 2002:a17:907:cf92:b0:7bf:7a65:b242 with SMTP id ux18-20020a170907cf9200b007bf7a65b242mr1924588ejc.356.1669569492906; Sun, 27 Nov 2022 09:18:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669569492; cv=none; d=google.com; s=arc-20160816; b=Acd2xKOJCoU08E9CdpZWT5K9m8BN+9TIySq4lRbV04ov5F0czWFH2VGot/TqxinN24 VJ7LfC0RxZu+7QjxO/zs6SupB/59MoKs0c9Ud9HCqDiBrKux7Leer+JpcprcfDL10dj+ nRJgqSHA4lOYkotylQU1Ka4By7y8aFoTqUO5UjE9tsm5xo1YGUC9KXmQmfZEnZYomTzi tS6a8NRT4dpuqW/+/S6gY1ZDWdZLsXKygmww1lTwCWkH8ZE5XXH5mnF18S47KyJtQg/8 VzHKHdJrCE3ybB8L4d6XkoVse4+1FKfEI8wjQ4n55K17LmMTT64y3EFWfDRb+NRlu8tZ tMPg== 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:message-id:date:to:from:subject; bh=No1z+Cn5CIL2zFaLj7CbtCItJHCAUmHRrGvNQuZKkp4=; b=YSIhLxaHdnUlPjl3DqGBiw0pzfssOvyCMo5XmH/3sFW2mxpTNsTkYV3MDhd0tMmR8Z D3+ggnJbP1XlrOuC2Ws5f0qZ+yOo2Ut2E56KuA5jClyWxnC8kZ0j9omRwePy2BfYHZT0 wRAAbztXX1YjKVK/GyBEHlrUCl24rHtBcSmFJ5wz72HgqMweEGYvSmABZDWvD4zGsmvV UB+vNN++jlUM7jIs3J1qB1x/7Tdsx+shAlStQ1q+Arxkm5BATxJJRRz8mWDh4eDGwacO yIj4etc+5qirKPjpus4YtMQdDw0yE5d+fzqpNn77s2YYiCPz0um6ZtACqzfRrtezTA2r y0Lw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=oracle.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id be4-20020a1709070a4400b006feb76dbd51si8859745ejc.289.2022.11.27.09.17.38; Sun, 27 Nov 2022 09:18:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229475AbiK0RRe (ORCPT + 99 others); Sun, 27 Nov 2022 12:17:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229500AbiK0RRe (ORCPT ); Sun, 27 Nov 2022 12:17:34 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD0CABD5 for ; Sun, 27 Nov 2022 09:17:31 -0800 (PST) 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 sin.source.kernel.org (Postfix) with ESMTPS id 4C807CE0B16 for ; Sun, 27 Nov 2022 17:17:30 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 74D78C433D6 for ; Sun, 27 Nov 2022 17:17:28 +0000 (UTC) Subject: [PATCH] SUNRPC: Fix crasher in unwrap_integ_data() From: Chuck Lever To: linux-nfs@vger.kernel.org Date: Sun, 27 Nov 2022 12:17:27 -0500 Message-ID: <166956944745.113279.2771726273440100988.stgit@klimt.1015granger.net> User-Agent: StGit/1.5.dev3+g9561319 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-6.7 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS autolearn=ham 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-nfs@vger.kernel.org If a zero length is passed to kmalloc() it returns 0x10, which is not a valid address. gss_verify_mic() subsequently crashes when it attempts to dereference that pointer. Instead of allocating this memory on every call based on an untrusted size value, use a piece of dynamically-allocated scratch memory that is always available. Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/svcauth_gss.c | 55 ++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 9a5db285d4ae..148bb0a7fa5b 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -49,11 +49,36 @@ #include #include #include +#include #include #include "gss_rpc_upcall.h" +/* + * Unfortunately there isn't a maximum checksum size exported via the + * GSS API. Manufacture one based on GSS mechanisms supported by this + * implementation. + */ +#define GSS_MAX_CKSUMSIZE (GSS_KRB5_TOK_HDR_LEN + GSS_KRB5_MAX_CKSUM_LEN) + +/* + * This value may be increased in the future to accommodate other + * usage of the scratch buffer. + */ +#define GSS_SCRATCH_SIZE GSS_MAX_CKSUMSIZE + +struct gss_svc_data { + /* decoded gss client cred: */ + struct rpc_gss_wire_cred clcred; + /* save a pointer to the beginning of the encoded verifier, + * for use in encryption/checksumming in svcauth_gss_release: */ + __be32 *verf_start; + struct rsc *rsci; + + /* for temporary results */ + u8 gsd_scratch[GSS_SCRATCH_SIZE]; +}; /* The rpcsec_init cache is used for mapping RPCSEC_GSS_{,CONT_}INIT requests * into replies. @@ -887,13 +912,11 @@ read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj) static int unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx) { + struct gss_svc_data *gsd = rqstp->rq_auth_data; u32 integ_len, rseqno, maj_stat; - int stat = -EINVAL; struct xdr_netobj mic; struct xdr_buf integ_buf; - mic.data = NULL; - /* NFS READ normally uses splice to send data in-place. However * the data in cache can change after the reply's MIC is computed * but before the RPC reply is sent. To prevent the client from @@ -917,11 +940,9 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g /* copy out mic... */ if (read_u32_from_xdr_buf(buf, integ_len, &mic.len)) goto unwrap_failed; - if (mic.len > RPC_MAX_AUTH_SIZE) - goto unwrap_failed; - mic.data = kmalloc(mic.len, GFP_KERNEL); - if (!mic.data) + if (mic.len > sizeof(gsd->gsd_scratch)) goto unwrap_failed; + mic.data = gsd->gsd_scratch; if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len)) goto unwrap_failed; maj_stat = gss_verify_mic(ctx, &integ_buf, &mic); @@ -932,20 +953,17 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g goto bad_seqno; /* trim off the mic and padding at the end before returning */ xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4); - stat = 0; -out: - kfree(mic.data); - return stat; + return 0; unwrap_failed: trace_rpcgss_svc_unwrap_failed(rqstp); - goto out; + return -EINVAL; bad_seqno: trace_rpcgss_svc_seqno_bad(rqstp, seq, rseqno); - goto out; + return -EINVAL; bad_mic: trace_rpcgss_svc_mic(rqstp, maj_stat); - goto out; + return -EINVAL; } static inline int @@ -1023,15 +1041,6 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs return -EINVAL; } -struct gss_svc_data { - /* decoded gss client cred: */ - struct rpc_gss_wire_cred clcred; - /* save a pointer to the beginning of the encoded verifier, - * for use in encryption/checksumming in svcauth_gss_release: */ - __be32 *verf_start; - struct rsc *rsci; -}; - static int svcauth_gss_set_client(struct svc_rqst *rqstp) {