Tue Dec 20 09:40:09 2022 UTC ()
When partitioning a mbuf chain with m_split() the last mbuf of the returned
tail chain is not necessarily the same as the last mbuf of the initial chain.

Always set "slp->ns_rawend" to the last mbuf of the tail chain to prevent
mbuf leaks and corruption.


(hannken)
diff -r1.4 -r1.5 src/sys/nfs/nfs_srvsocket.c

cvs diff -r1.4 -r1.5 src/sys/nfs/nfs_srvsocket.c (expand / switch to unified diff)

--- src/sys/nfs/nfs_srvsocket.c 2009/09/03 20:59:12 1.4
+++ src/sys/nfs/nfs_srvsocket.c 2022/12/20 09:40:09 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nfs_srvsocket.c,v 1.4 2009/09/03 20:59:12 tls Exp $ */ 1/* $NetBSD: nfs_srvsocket.c,v 1.5 2022/12/20 09:40:09 hannken Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1989, 1991, 1993, 1995 4 * Copyright (c) 1989, 1991, 1993, 1995
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph. 8 * Rick Macklem at The University of Guelph.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95 34 * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
35 */ 35 */
36 36
37/* 37/*
38 * Socket operations for use by nfs 38 * Socket operations for use by nfs
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42__KERNEL_RCSID(0, "$NetBSD: nfs_srvsocket.c,v 1.4 2009/09/03 20:59:12 tls Exp $"); 42__KERNEL_RCSID(0, "$NetBSD: nfs_srvsocket.c,v 1.5 2022/12/20 09:40:09 hannken Exp $");
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/evcnt.h> 46#include <sys/evcnt.h>
47#include <sys/callout.h> 47#include <sys/callout.h>
48#include <sys/proc.h> 48#include <sys/proc.h>
49#include <sys/mount.h> 49#include <sys/mount.h>
50#include <sys/kernel.h> 50#include <sys/kernel.h>
51#include <sys/kmem.h> 51#include <sys/kmem.h>
52#include <sys/mbuf.h> 52#include <sys/mbuf.h>
53#include <sys/vnode.h> 53#include <sys/vnode.h>
54#include <sys/domain.h> 54#include <sys/domain.h>
55#include <sys/protosw.h> 55#include <sys/protosw.h>
@@ -313,28 +313,29 @@ nfsrv_getstream(struct nfssvc_sock *slp, @@ -313,28 +313,29 @@ nfsrv_getstream(struct nfssvc_sock *slp,
313 if (slp->ns_cc == slp->ns_reclen) { 313 if (slp->ns_cc == slp->ns_reclen) {
314 recm = slp->ns_raw; 314 recm = slp->ns_raw;
315 slp->ns_raw = slp->ns_rawend = (struct mbuf *)0; 315 slp->ns_raw = slp->ns_rawend = (struct mbuf *)0;
316 slp->ns_cc = slp->ns_reclen = 0; 316 slp->ns_cc = slp->ns_reclen = 0;
317 } else if (slp->ns_cc > slp->ns_reclen) { 317 } else if (slp->ns_cc > slp->ns_reclen) {
318 recm = slp->ns_raw; 318 recm = slp->ns_raw;
319 m = m_split(recm, slp->ns_reclen, waitflag); 319 m = m_split(recm, slp->ns_reclen, waitflag);
320 if (m == NULL) { 320 if (m == NULL) {
321 error = EWOULDBLOCK; 321 error = EWOULDBLOCK;
322 break; 322 break;
323 } 323 }
324 m_claimm(recm, &nfs_mowner); 324 m_claimm(recm, &nfs_mowner);
325 slp->ns_raw = m; 325 slp->ns_raw = m;
326 if (m->m_next == NULL) 326 while (m->m_next)
327 slp->ns_rawend = m; 327 m = m->m_next;
 328 slp->ns_rawend = m;
328 slp->ns_cc -= slp->ns_reclen; 329 slp->ns_cc -= slp->ns_reclen;
329 slp->ns_reclen = 0; 330 slp->ns_reclen = 0;
330 } else { 331 } else {
331 break; 332 break;
332 } 333 }
333 334
334 /* 335 /*
335 * Accumulate the fragments into a record. 336 * Accumulate the fragments into a record.
336 */ 337 */
337 mpp = &slp->ns_frag; 338 mpp = &slp->ns_frag;
338 while (*mpp) 339 while (*mpp)
339 mpp = &((*mpp)->m_next); 340 mpp = &((*mpp)->m_next);
340 *mpp = recm; 341 *mpp = recm;