From patchwork Mon Feb 22 17:43:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Frederic Sowa X-Patchwork-Id: 586428 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 64A991409A0 for ; Tue, 23 Feb 2016 04:43:43 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=stressinduktion.org header.i=@stressinduktion.org header.b=RfhXWFhW; dkim=pass (1024-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b=kdqvG46o; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752042AbcBVRnf (ORCPT ); Mon, 22 Feb 2016 12:43:35 -0500 Received: from out4-smtp.messagingengine.com ([66.111.4.28]:36188 "EHLO out4-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751096AbcBVRne (ORCPT ); Mon, 22 Feb 2016 12:43:34 -0500 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id 219B720D2C for ; Mon, 22 Feb 2016 12:43:34 -0500 (EST) Received: from frontend1 ([10.202.2.160]) by compute3.internal (MEProxy); Mon, 22 Feb 2016 12:43:34 -0500 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= stressinduktion.org; h=cc:date:from:message-id:subject:to :x-sasl-enc:x-sasl-enc; s=mesmtp; bh=Is0Czde0iM2w7MTCrAQjTOHb1FY =; b=RfhXWFhWI+9NZ//TFWOfwULZWXbpF/F/uV3hBz6akYGcZhlyJ0Bo4CpPjQV beKZ5Wxbt7s5xSAYgcA3PPXbsupOEG5vvhYl4KIM38o9x1Kb59n2egoJTnjHGMv1 cgD/VliFrdcvmxnZD/84D0V7d94/nQndJyc/ui3fsyKkRve0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:message-id:subject:to :x-sasl-enc:x-sasl-enc; s=smtpout; bh=Is0Czde0iM2w7MTCrAQjTOHb1F Y=; b=kdqvG46oc7RnjFTbgu2dNST7/RWIFrODLEOh8GgwCXfKJCE6eGcDX/T7nV i4Rjx8BBZryYeW7OG2bes3V3RJSdafGPqslCfnlwhZSazl0fniVgpgLVyCSd5qlg JPhUzQMwuc7sSxK1uu1xIDBC0gx1fn5hZIZb9uxSzoB1LY4YY= X-Sasl-enc: oSvPcZX/byJ8w7JBboiCsy8UoVu85tCdRUCqPSbODotN 1456163013 Received: from z.localhost.localdomain (unknown [213.55.176.241]) by mail.messagingengine.com (Postfix) with ESMTPA id D82DDC00013; Mon, 22 Feb 2016 12:43:32 -0500 (EST) From: Hannes Frederic Sowa To: netdev@vger.kernel.org Cc: Jiri Benc , Wakko Warner Subject: [PATCH net] ipv4: only create late gso-skb if skb is already set up with CHECKSUM_PARTIAL Date: Mon, 22 Feb 2016 18:43:25 +0100 Message-Id: <1456163005-15809-1-git-send-email-hannes@stressinduktion.org> X-Mailer: git-send-email 2.5.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Otherwise we break the contract with GSO to only pass CHECKSUM_PARTIAL skbs down. This can easily happen with UDP+IPv4 sockets with the first MSG_MORE write smaller than the MTU, second write is a sendfile. Returning -EOPNOTSUPP lets the callers fall back into normal sendmsg path, were we calculate the checksum manually during copying. Commit d749c9cbffd6 ("ipv4: no CHECKSUM_PARTIAL on MSG_MORE corked sockets") started to exposes this bug. Fixes: d749c9cbffd6 ("ipv4: no CHECKSUM_PARTIAL on MSG_MORE corked sockets") Reported-by: Jiri Benc Cc: Jiri Benc Reported-by: Wakko Warner Cc: Wakko Warner Signed-off-by: Hannes Frederic Sowa --- net/ipv4/ip_output.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 64878efa045c13..565bf64b2b7d60 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1236,13 +1236,16 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page, if (!skb) return -EINVAL; - cork->length += size; if ((size + skb->len > mtu) && (sk->sk_protocol == IPPROTO_UDP) && (rt->dst.dev->features & NETIF_F_UFO)) { + if (skb->ip_summed != CHECKSUM_PARTIAL) + return -EOPNOTSUPP; + skb_shinfo(skb)->gso_size = mtu - fragheaderlen; skb_shinfo(skb)->gso_type = SKB_GSO_UDP; } + cork->length += size; while (size > 0) { if (skb_is_gso(skb)) {