From patchwork Tue Oct 25 06:06:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 10512 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp835358wru; Mon, 24 Oct 2022 23:18:36 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5O0VTnzBfG5CztLJ4E/3J11kJgYxwB0l5nOxlTUxe/J6hkHB1XgM8Tn4m+T4Lg59QBcwGa X-Received: by 2002:a17:902:c94e:b0:181:4ab4:179b with SMTP id i14-20020a170902c94e00b001814ab4179bmr38297572pla.126.1666678715861; Mon, 24 Oct 2022 23:18:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666678715; cv=none; d=google.com; s=arc-20160816; b=fLUg3l5Xf8VDPMEo+hkqhEMrGLQH3HfG3l7/i21qWtiu5UtGMr8qGdayLj9qIH3qWj B1cFjwRICB1gGnssmW/QPo1i8YD4n/QG5VdJmzBJqbOb/AaN+mA91KaSUEd/d8gQLJBk gmrtBOowvH6jT1/xYzWkenoRRZVIY5uMo7usayf8G14XU9VT+xaqG1Q8X0ytuxswir5t JsJ/ZraNo6q6Og6D3gOIiglxDhYVQYTZC+6Gdkmx014hX/Gx3yf7W3/wdeX8cu5TeuJs 24vJta5ULB6jW2yqKt5sttEcChTjifEkLf22ZZ3E4cvjgVrtboyTptD/7HUZXvev64ED BCgg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date; bh=atbDoSI2awk9g5Jy+YdypR8rs5loopF8UbkIxSNuLec=; b=bDK3yWVdoPPmeWA809tpk/pIiOH0O4aAgBqCznBPGIEHEMQIn2iltkoJXCnzY26Vf8 p/YUp6kjIXkjs33YHGd1DQVYU6fRKyfWWJQKQZQOfXNhDAzxMbAOL78g+ANVO+MXU3pL WheEo3pUHGogLP6HYkWXUwM+o8Mskbp45jbYXfRiM6N7x0+LhmTLnogV4MGAljw4FduV jf/s84q95YKux5mWQ0XIkcWHJS+9jfjlrRl3l/gsMVSDSzveJ5jVp384J9WJoPIHZyBz 4umRT9qioOlvY0BciHScWc5xLIQcuGoGZDbMnGAZmpYaJuHcgxCruNmVKOemL2dhjo1M FgCA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k1-20020a170902c40100b0017f914799b4si2405590plk.175.2022.10.24.23.18.22; Mon, 24 Oct 2022 23:18:35 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-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-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230526AbiJYGHI (ORCPT + 99 others); Tue, 25 Oct 2022 02:07:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230221AbiJYGHG (ORCPT ); Tue, 25 Oct 2022 02:07:06 -0400 Received: from formenos.hmeau.com (helcar.hmeau.com [216.24.177.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12A9EABD4D; Mon, 24 Oct 2022 23:07:05 -0700 (PDT) Received: from loth.rohan.me.apana.org.au ([192.168.167.2]) by formenos.hmeau.com with smtp (Exim 4.94.2 #2 (Debian)) id 1onD4l-0064BC-Tl; Tue, 25 Oct 2022 14:06:49 +0800 Received: by loth.rohan.me.apana.org.au (sSMTP sendmail emulation); Tue, 25 Oct 2022 14:06:48 +0800 Date: Tue, 25 Oct 2022 14:06:48 +0800 From: Herbert Xu To: Sabrina Dubroca Cc: Eric Dumazet , syzbot , davem@davemloft.net, kuba@kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, pabeni@redhat.com, steffen.klassert@secunet.com, syzkaller-bugs@googlegroups.com Subject: [v3 PATCH] af_key: Fix send_acquire race with pfkey_register Message-ID: References: <000000000000fd9a4005ebbeac67@google.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,URIBL_BLOCKED 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-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747544653954945244?= X-GMAIL-MSGID: =?utf-8?q?1747639300889406494?= On Mon, Oct 24, 2022 at 09:20:00AM +0200, Sabrina Dubroca wrote: > 2022-10-24, 14:06:12 +0800, Herbert Xu wrote: > > @@ -1697,11 +1699,11 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, const struct sad > > pfk->registered |= (1<sadb_msg_satype); > > } > > > > - mutex_lock(&pfkey_mutex); > > + spin_lock_bh(&pfkey_alg_lock); > > xfrm_probe_algs(); > > I don't think we can do that: > > void xfrm_probe_algs(void) > { > int i, status; > > BUG_ON(in_softirq()); Indeed. I was also wrong in stating that this bug was created by namespaces. This race has always existed since this code was first added. ---8<--- The function pfkey_send_acquire may race with pfkey_register (which could even be in a different name space). This may result in a buffer overrun. Allocating the maximum amount of memory that could be used prevents this. Reported-by: syzbot+1e9af9185d8850e2c2fa@syzkaller.appspotmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Herbert Xu Reviewed-by: Sabrina Dubroca Reviewed-by: Eric Dumazet diff --git a/net/key/af_key.c b/net/key/af_key.c index c85df5b958d2..213287814328 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2905,7 +2905,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t) break; if (!aalg->pfkey_supported) continue; - if (aalg_tmpl_set(t, aalg) && aalg->available) + if (aalg_tmpl_set(t, aalg)) sz += sizeof(struct sadb_comb); } return sz + sizeof(struct sadb_prop); @@ -2923,7 +2923,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t) if (!ealg->pfkey_supported) continue; - if (!(ealg_tmpl_set(t, ealg) && ealg->available)) + if (!(ealg_tmpl_set(t, ealg))) continue; for (k = 1; ; k++) { @@ -2934,16 +2934,17 @@ static int count_esp_combs(const struct xfrm_tmpl *t) if (!aalg->pfkey_supported) continue; - if (aalg_tmpl_set(t, aalg) && aalg->available) + if (aalg_tmpl_set(t, aalg)) sz += sizeof(struct sadb_comb); } } return sz + sizeof(struct sadb_prop); } -static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) +static int dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) { struct sadb_prop *p; + int sz = 0; int i; p = skb_put(skb, sizeof(struct sadb_prop)); @@ -2971,13 +2972,17 @@ static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) c->sadb_comb_soft_addtime = 20*60*60; c->sadb_comb_hard_usetime = 8*60*60; c->sadb_comb_soft_usetime = 7*60*60; + sz += sizeof(*c); } } + + return sz + sizeof(*p); } -static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) +static int dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) { struct sadb_prop *p; + int sz = 0; int i, k; p = skb_put(skb, sizeof(struct sadb_prop)); @@ -3019,8 +3024,11 @@ static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t) c->sadb_comb_soft_addtime = 20*60*60; c->sadb_comb_hard_usetime = 8*60*60; c->sadb_comb_soft_usetime = 7*60*60; + sz += sizeof(*c); } } + + return sz + sizeof(*p); } static int key_notify_policy_expire(struct xfrm_policy *xp, const struct km_event *c) @@ -3150,6 +3158,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct struct sadb_x_sec_ctx *sec_ctx; struct xfrm_sec_ctx *xfrm_ctx; int ctx_size = 0; + int alg_size = 0; sockaddr_size = pfkey_sockaddr_size(x->props.family); if (!sockaddr_size) @@ -3161,16 +3170,16 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct sizeof(struct sadb_x_policy); if (x->id.proto == IPPROTO_AH) - size += count_ah_combs(t); + alg_size = count_ah_combs(t); else if (x->id.proto == IPPROTO_ESP) - size += count_esp_combs(t); + alg_size = count_esp_combs(t); if ((xfrm_ctx = x->security)) { ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len); size += sizeof(struct sadb_x_sec_ctx) + ctx_size; } - skb = alloc_skb(size + 16, GFP_ATOMIC); + skb = alloc_skb(size + alg_size + 16, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; @@ -3224,10 +3233,13 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct pol->sadb_x_policy_priority = xp->priority; /* Set sadb_comb's. */ + alg_size = 0; if (x->id.proto == IPPROTO_AH) - dump_ah_combs(skb, t); + alg_size = dump_ah_combs(skb, t); else if (x->id.proto == IPPROTO_ESP) - dump_esp_combs(skb, t); + alg_size = dump_esp_combs(skb, t); + + hdr->sadb_msg_len += alg_size / 8; /* security context */ if (xfrm_ctx) {