From owner-svn-src-stable-8@FreeBSD.ORG Wed Jul 3 03:40:06 2013 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id C8B0DC1E; Wed, 3 Jul 2013 03:40:06 +0000 (UTC) (envelope-from lstewart@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id BBA5A1951; Wed, 3 Jul 2013 03:40:06 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r633e6nV005392; Wed, 3 Jul 2013 03:40:06 GMT (envelope-from lstewart@svn.freebsd.org) Received: (from lstewart@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r633e6RZ005391; Wed, 3 Jul 2013 03:40:06 GMT (envelope-from lstewart@svn.freebsd.org) Message-Id: <201307030340.r633e6RZ005391@svn.freebsd.org> From: Lawrence Stewart Date: Wed, 3 Jul 2013 03:40:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r252533 - stable/8/sys/kern X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jul 2013 03:40:06 -0000 Author: lstewart Date: Wed Jul 3 03:40:06 2013 New Revision: 252533 URL: http://svnweb.freebsd.org/changeset/base/252533 Log: When a previous call to sbsndptr() leaves sb->sb_sndptroff at the start of an mbuf that was fully consumed by the previous call, the mbuf ptr returned by the current call ends up being the previous mbuf in the sb chain to the one that contains the data we want. This does not cause any observable issues because the mbuf copy routines happily walk the mbuf chain to get to the data at the moff offset, which in this case means they effectively skip over the mbuf returned by sbsndptr(). We can't adjust sb->sb_sndptr during the previous call for this case because the next mbuf in the chain may not exist yet. We therefore need to detect the condition and make the adjustment during the current call. Fix by detecting the special case of moff being at the start of the next mbuf in the chain and adjust the required accounting variables accordingly. Reviewed by: andre Modified: stable/8/sys/kern/uipc_sockbuf.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/kern/ (props changed) Modified: stable/8/sys/kern/uipc_sockbuf.c ============================================================================== --- stable/8/sys/kern/uipc_sockbuf.c Wed Jul 3 03:36:36 2013 (r252532) +++ stable/8/sys/kern/uipc_sockbuf.c Wed Jul 3 03:40:06 2013 (r252533) @@ -939,6 +939,13 @@ sbsndptr(struct sockbuf *sb, u_int off, /* Return closest mbuf in chain for current offset. */ *moff = off - sb->sb_sndptroff; m = ret = sb->sb_sndptr ? sb->sb_sndptr : sb->sb_mb; + if (*moff == m->m_len) { + *moff = 0; + sb->sb_sndptroff += m->m_len; + m = ret = m->m_next; + KASSERT(ret->m_len > 0, + ("mbuf %p in sockbuf %p chain has no valid data", ret, sb)); + } /* Advance by len to be as close as possible for the next transmit. */ for (off = off - sb->sb_sndptroff + len - 1;