From patchwork Thu Mar 14 15:40:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Dumazet X-Patchwork-Id: 227719 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 9DF1C2C00B6 for ; Fri, 15 Mar 2013 02:40:43 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758103Ab3CNPki (ORCPT ); Thu, 14 Mar 2013 11:40:38 -0400 Received: from mail-ee0-f44.google.com ([74.125.83.44]:39129 "EHLO mail-ee0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758004Ab3CNPkh (ORCPT ); Thu, 14 Mar 2013 11:40:37 -0400 Received: by mail-ee0-f44.google.com with SMTP id l10so1104837eei.17 for ; Thu, 14 Mar 2013 08:40:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:message-id:subject:from:to:cc:date:content-type:x-mailer :content-transfer-encoding:mime-version; bh=/zQmZUwz83eB6UCZiXmdGUL0HNm2uoyOoqTx4NJogIM=; b=eO5zRSR2373EkFaIhnuY1ofGeAdsiuPnb6d1K40h+4oP1S+fd0xcp2f67RoTlzWctL C9FEkXEVUlTd57+tlSeOWi5eViA7iIu1lbAJIoGWnWP9ural4Tf5Dku3eMmj7YNsh9GW Wr8aL2+DD9L4e+RfJUqj6kbNsSoTurmd9ihHUU3PQIVqgFBKw7S4TJqIA3aGjYDrkz0S t/cbuBfTTyfZLoFrw5UK7jnaumpwW/qNnqQ+Pqfx5s3B7N50L63ZAEitLlQa9nWltK5+ gAsSubH+41/OOTZMOCeyibx2DZ4e7ezVqi3d8aBJKOXLZjCrcQBZBqNNW0abj728ORMg A0ag== X-Received: by 10.15.43.132 with SMTP id x4mr7952326eev.31.1363275634888; Thu, 14 Mar 2013 08:40:34 -0700 (PDT) Received: from [172.16.38.10] ([172.16.38.10]) by mx.google.com with ESMTPS id q5sm4343558eeo.17.2013.03.14.08.40.33 (version=SSLv3 cipher=RC4-SHA bits=128/128); Thu, 14 Mar 2013 08:40:34 -0700 (PDT) Message-ID: <1363275632.29475.32.camel@edumazet-glaptop> Subject: [PATCH] tcp: fix skb_availroom() From: Eric Dumazet To: David Miller Cc: netdev , Mukesh Agrawal Date: Thu, 14 Mar 2013 16:40:32 +0100 X-Mailer: Evolution 3.2.3-0ubuntu6 Mime-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Eric Dumazet Chrome OS team reported a crash on a Pixel ChromeBook in TCP stack : https://code.google.com/p/chromium/issues/detail?id=182056 commit a21d45726acac (tcp: avoid order-1 allocations on wifi and tx path) did a poor choice adding an 'avail_size' field to skb, while what we really needed was a 'reserved_tailroom' one. It would have avoided commit 22b4a4f22da (tcp: fix retransmit of partially acked frames) and this commit. Crash occurs because skb_split() is not aware of the 'avail_size' management (and should not be aware) Signed-off-by: Eric Dumazet Reported-by: Mukesh Agrawal --- include/linux/skbuff.h | 7 +++++-- net/ipv4/tcp.c | 2 +- net/ipv4/tcp_output.c | 1 - 3 files changed, 6 insertions(+), 4 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 821c7f4..6f2bb86 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -500,7 +500,7 @@ struct sk_buff { union { __u32 mark; __u32 dropcount; - __u32 avail_size; + __u32 reserved_tailroom; }; sk_buff_data_t inner_transport_header; @@ -1447,7 +1447,10 @@ static inline int skb_tailroom(const struct sk_buff *skb) */ static inline int skb_availroom(const struct sk_buff *skb) { - return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len; + if (skb_is_nonlinear(skb)) + return 0; + + return skb->end - skb->tail - skb->reserved_tailroom; } /** diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 47e854f..e220207 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -775,7 +775,7 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp) * Make sure that we have exactly size bytes * available to the caller, no more, no less. */ - skb->avail_size = size; + skb->reserved_tailroom = skb->end - skb->tail - size; return skb; } __kfree_skb(skb); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index e2b4461..817fbb3 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1298,7 +1298,6 @@ static void __pskb_trim_head(struct sk_buff *skb, int len) eat = min_t(int, len, skb_headlen(skb)); if (eat) { __skb_pull(skb, eat); - skb->avail_size -= eat; len -= eat; if (!len) return;