From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752142AbXCRMn4 (ORCPT ); Sun, 18 Mar 2007 08:43:56 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752324AbXCRMn4 (ORCPT ); Sun, 18 Mar 2007 08:43:56 -0400 Received: from noname.neutralserver.com ([70.84.186.210]:34468 "EHLO noname.neutralserver.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1752142AbXCRMnz (ORCPT ); Sun, 18 Mar 2007 08:43:55 -0400 Date: Sun, 18 Mar 2007 14:43:46 +0200 From: Dan Aloni To: Linux Kernel List Cc: netdev@vger.kernel.org Subject: [PATCH] tcp_sendpage(): fix broken page iteration Message-ID: <20070318124346.GA6396@localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.13 (2006-08-11) X-PopBeforeSMTPSenders: da-x@monatomic.org X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - noname.neutralserver.com X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [0 0] / [47 12] X-AntiAbuse: Sender Address Domain - monatomic.org X-Source: X-Source-Args: X-Source-Dir: Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org do_tcp_sendpages() should not iterate 'pages' as an array since it is not an array of 'struct page *', but a pointer to a single entity of 'struct page *' passed on the stack as a parameter to tcp_send_page() (hence it would crash if poffset + psize > PAGE_SIZE, because pages[1] and beyond most probably not constitutes a valid 'struct page *'). Since 'page' points to an array of 'struct page', the obvious fix is to iterate that array instead, and that's what the function should have done in the first place. Applies to 2.6.21-rc4 and above. diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 3834b10..4881c8d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -501,7 +501,7 @@ static inline void tcp_push(struct sock *sk, struct tcp_sock *tp, int flags, } } -static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, +static ssize_t do_tcp_sendpages(struct sock *sk, struct page *pages, int poffset, size_t psize, int flags) { struct tcp_sock *tp = tcp_sk(sk); @@ -527,7 +527,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse while (psize > 0) { struct sk_buff *skb = sk->sk_write_queue.prev; - struct page *page = pages[poffset / PAGE_SIZE]; + struct page *page = &pages[poffset / PAGE_SIZE]; int copy, i, can_coalesce; int offset = poffset % PAGE_SIZE; int size = min_t(size_t, psize, PAGE_SIZE - offset); @@ -630,7 +630,7 @@ ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, lock_sock(sk); TCP_CHECK_TIMER(sk); - res = do_tcp_sendpages(sk, &page, offset, size, flags); + res = do_tcp_sendpages(sk, page, offset, size, flags); TCP_CHECK_TIMER(sk); release_sock(sk); return res; -- Dan Aloni XIV LTD, http://www.xivstorage.com da-x (at) monatomic.org, dan (at) xiv.co.il