Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp3314029pxf; Mon, 5 Apr 2021 08:48:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwwrwsvDZysh2/+Qf3L7rbvInNwGOjIABq/YQ1N6M+1ViUrM72lR4Alm/khQWRgqPzx8fV7 X-Received: by 2002:a05:6602:2f0c:: with SMTP id q12mr20000303iow.82.1617637701201; Mon, 05 Apr 2021 08:48:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617637701; cv=none; d=google.com; s=arc-20160816; b=QnrO46coJpnDUf9wgpY5EX0MTcgHdVAQPUBzYBetxl566FZmJw6bzOQwToQW4XAQXJ /0dlqOjn0A3AZVLrN0NY8A0O8L3YcJB3FhL0Nf7xcSPfEggU0cv0SzkLNwMtQ+6vLF78 xl0WhEqVdJMZ76YraKy9ocoK7ylj36GMJ2+KBxuMLBvHSwZltGyWRAgbmqiCy5XfDPJF 8wVM/kJpDwC2Cms+N+4Rp+K7QfOA5vSgQXZgCTw/QKqviS9kqz4PTcge7pItJr+/5Z5s 4EvhmMa9XExvPPANrCOLI5GUS7F+GUXzvdUQpYb035n7t5V8Yrku/ZL10mmoaNyXQdS8 g0gw== 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=CiE2pSwhbdtt+8+BYalww9KUJnesrdnY0bQIagbaaAg=; b=pAPC0hFswQHoByDy39Jbmp4+KiGWoS+AE5/HNqEcYa8h1E6qbkv1NVaI2vtSQcejm5 GTObujayw53kr2IcOp+XHBV2HlVRO67eSbFa9bI9w/QuSNZet6Ooeh1lX8WedClkzcVy SAngAIxTyyiwzBit1eMMGznjLMz8aSZooHcVdoOovwpllN0BzyA7NoQh07c9kv+cZRG0 Z+kvWf5xyhJ3HWXb2XV+CUeSbYpMNbgH5bgkboQmzC6CyZHw2rWzORQEh6qH4kSc/4x5 azarr+kXs4VJz6HCokl7Zdsi7C6TeyGaxFmgmAorQyrZB6PRopU49yoiFZUePA+YBQDp x8sw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=yFpJVWc4; 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 x21si14537318jaq.64.2021.04.05.08.48.08; Mon, 05 Apr 2021 08:48:21 -0700 (PDT) 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=yFpJVWc4; 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 S237930AbhDEJG4 (ORCPT + 99 others); Mon, 5 Apr 2021 05:06:56 -0400 Received: from mail.kernel.org ([198.145.29.99]:47802 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237865AbhDEJEJ (ORCPT ); Mon, 5 Apr 2021 05:04:09 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 5A02A6138D; Mon, 5 Apr 2021 09:04:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1617613444; bh=tWMRUvF7SlrT4dd749FELOPzIVyb99tZTqeUIanoMac=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=yFpJVWc4jslE2cGmQNifJWj7VcYrGIxT2J7AaVkmRhDBGZd7Te5pkM772hipRsCFX VQHXhJXRKKFUyjQr2MH9xsXD+pmfBEQ7qL82KQUBQekMSzDY5/Cg0fOcr2JeW2XB9m 9qndThI/pHqQgEZryUwwOseTjwjQ9TpYMJgdY8CM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Doug Brown , "David S. Miller" , Sasha Levin Subject: [PATCH 5.4 38/74] appletalk: Fix skb allocation size in loopback case Date: Mon, 5 Apr 2021 10:54:02 +0200 Message-Id: <20210405085025.975810824@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210405085024.703004126@linuxfoundation.org> References: <20210405085024.703004126@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: Doug Brown [ Upstream commit 39935dccb21c60f9bbf1bb72d22ab6fd14ae7705 ] If a DDP broadcast packet is sent out to a non-gateway target, it is also looped back. There is a potential for the loopback device to have a longer hardware header length than the original target route's device, which can result in the skb not being created with enough room for the loopback device's hardware header. This patch fixes the issue by determining that a loopback will be necessary prior to allocating the skb, and if so, ensuring the skb has enough room. This was discovered while testing a new driver that creates a LocalTalk network interface (LTALK_HLEN = 1). It caused an skb_under_panic. Signed-off-by: Doug Brown Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/appletalk/ddp.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index b41375d4d295..4610c352849b 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1568,8 +1568,8 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) struct sk_buff *skb; struct net_device *dev; struct ddpehdr *ddp; - int size; - struct atalk_route *rt; + int size, hard_header_len; + struct atalk_route *rt, *rt_lo = NULL; int err; if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) @@ -1632,7 +1632,22 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", sk, size, dev->name); - size += dev->hard_header_len; + hard_header_len = dev->hard_header_len; + /* Leave room for loopback hardware header if necessary */ + if (usat->sat_addr.s_node == ATADDR_BCAST && + (dev->flags & IFF_LOOPBACK || !(rt->flags & RTF_GATEWAY))) { + struct atalk_addr at_lo; + + at_lo.s_node = 0; + at_lo.s_net = 0; + + rt_lo = atrtr_find(&at_lo); + + if (rt_lo && rt_lo->dev->hard_header_len > hard_header_len) + hard_header_len = rt_lo->dev->hard_header_len; + } + + size += hard_header_len; release_sock(sk); skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); lock_sock(sk); @@ -1640,7 +1655,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) goto out; skb_reserve(skb, ddp_dl->header_length); - skb_reserve(skb, dev->hard_header_len); + skb_reserve(skb, hard_header_len); skb->dev = dev; SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); @@ -1691,18 +1706,12 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) /* loop back */ skb_orphan(skb); if (ddp->deh_dnode == ATADDR_BCAST) { - struct atalk_addr at_lo; - - at_lo.s_node = 0; - at_lo.s_net = 0; - - rt = atrtr_find(&at_lo); - if (!rt) { + if (!rt_lo) { kfree_skb(skb); err = -ENETUNREACH; goto out; } - dev = rt->dev; + dev = rt_lo->dev; skb->dev = dev; } ddp_dl->request(ddp_dl, skb, dev->dev_addr); -- 2.30.1