On Fri, Sep 01, 2017 at 11:58:04AM +0200, Martin Pieuchot wrote:
> Diff below also includes another fix. Don't leave a dangling pointer
> in ip_pcbopts() by calling m_dup_pkt() as suggested by visa@. Note
> that if the allocation fails I'm returning ENOBUFS like in the IPv6
> case.
>
> ok?
OK bluhm@
>
> Index: kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.202
> diff -u -p -r1.202 uipc_socket.c
> --- kern/uipc_socket.c 22 Aug 2017 09:13:36 -0000 1.202
> +++ kern/uipc_socket.c 22 Aug 2017 15:12:58 -0000
> @@ -1558,17 +1558,16 @@ sowwakeup(struct socket *so)
> }
>
> int
> -sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
> +sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
> {
> int error = 0;
> - struct mbuf *m = m0;
>
> soassertlocked(so);
>
> if (level != SOL_SOCKET) {
> if (so->so_proto->pr_ctloutput) {
> error = (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
> - level, optname, m0);
> + level, optname, m);
> return (error);
> }
> error = ENOPROTOOPT;
> @@ -1576,7 +1575,7 @@ sosetopt(struct socket *so, int level, i
> switch (optname) {
> case SO_BINDANY:
> if ((error = suser(curproc, 0)) != 0) /* XXX */
> - goto bad;
> + return (error);
> break;
> }
>
> @@ -1585,10 +1584,8 @@ sosetopt(struct socket *so, int level, i
> case SO_LINGER:
> if (m == NULL || m->m_len != sizeof (struct linger) ||
> mtod(m, struct linger *)->l_linger < 0 ||
> - mtod(m, struct linger *)->l_linger > SHRT_MAX) {
> - error = EINVAL;
> - goto bad;
> - }
> + mtod(m, struct linger *)->l_linger > SHRT_MAX)
> + return (EINVAL);
> so->so_linger = mtod(m, struct linger *)->l_linger;
> /* FALLTHROUGH */
>
> @@ -1602,10 +1599,8 @@ sosetopt(struct socket *so, int level, i
> case SO_OOBINLINE:
> case SO_TIMESTAMP:
> case SO_ZEROIZE:
> - if (m == NULL || m->m_len < sizeof (int)) {
> - error = EINVAL;
> - goto bad;
> - }
> + if (m == NULL || m->m_len < sizeof (int))
> + return (EINVAL);
> if (*mtod(m, int *))
> so->so_options |= optname;
> else
> @@ -1613,10 +1608,8 @@ sosetopt(struct socket *so, int level, i
> break;
>
> case SO_DONTROUTE:
> - if (m == NULL || m->m_len < sizeof (int)) {
> - error = EINVAL;
> - goto bad;
> - }
> + if (m == NULL || m->m_len < sizeof (int))
> + return (EINVAL);
> if (*mtod(m, int *))
> error = EOPNOTSUPP;
> break;
> @@ -1628,38 +1621,28 @@ sosetopt(struct socket *so, int level, i
> {
> u_long cnt;
>
> - if (m == NULL || m->m_len < sizeof (int)) {
> - error = EINVAL;
> - goto bad;
> - }
> + if (m == NULL || m->m_len < sizeof (int))
> + return (EINVAL);
> cnt = *mtod(m, int *);
> if ((long)cnt <= 0)
> cnt = 1;
> switch (optname) {
>
> case SO_SNDBUF:
> - if (so->so_state & SS_CANTSENDMORE) {
> - error = EINVAL;
> - goto bad;
> - }
> + if (so->so_state & SS_CANTSENDMORE)
> + return (EINVAL);
> if (sbcheckreserve(cnt, so->so_snd.sb_wat) ||
> - sbreserve(so, &so->so_snd, cnt)) {
> - error = ENOBUFS;
> - goto bad;
> - }
> + sbreserve(so, &so->so_snd, cnt))
> + return (ENOBUFS);
> so->so_snd.sb_wat = cnt;
> break;
>
> case SO_RCVBUF:
> - if (so->so_state & SS_CANTRCVMORE) {
> - error = EINVAL;
> - goto bad;
> - }
> + if (so->so_state & SS_CANTRCVMORE)
> + return (EINVAL);
> if (sbcheckreserve(cnt, so->so_rcv.sb_wat) ||
> - sbreserve(so, &so->so_rcv, cnt)) {
> - error = ENOBUFS;
> - goto bad;
> - }
> + sbreserve(so, &so->so_rcv, cnt))
> + return (ENOBUFS);
> so->so_rcv.sb_wat = cnt;
> break;
>
> @@ -1683,16 +1666,12 @@ sosetopt(struct socket *so, int level, i
> struct timeval tv;
> int val;
>
> - if (m == NULL || m->m_len < sizeof (tv)) {
> - error = EINVAL;
> - goto bad;
> - }
> + if (m == NULL || m->m_len < sizeof (tv))
> + return (EINVAL);
> memcpy(&tv, mtod(m, struct timeval *), sizeof tv);
> val = tvtohz(&tv);
> - if (val > USHRT_MAX) {
> - error = EDOM;
> - goto bad;
> - }
> + if (val > USHRT_MAX)
> + return (EDOM);
>
> switch (optname) {
>
> @@ -1714,7 +1693,7 @@ sosetopt(struct socket *so, int level, i
>
> level = dom->dom_protosw->pr_protocol;
> error = (*so->so_proto->pr_ctloutput)
> - (PRCO_SETOPT, so, level, optname, m0);
> + (PRCO_SETOPT, so, level, optname, m);
> return (error);
> }
> error = ENOPROTOOPT;
> @@ -1725,8 +1704,7 @@ sosetopt(struct socket *so, int level, i
> if (m == NULL) {
> error = sosplice(so, -1, 0, NULL);
> } else if (m->m_len < sizeof(int)) {
> - error = EINVAL;
> - goto bad;
> + return (EINVAL);
> } else if (m->m_len < sizeof(struct splice)) {
> error = sosplice(so, *mtod(m, int *), 0, NULL);
> } else {
> @@ -1744,13 +1722,10 @@ sosetopt(struct socket *so, int level, i
> }
> if (error == 0 && so->so_proto->pr_ctloutput) {
> (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
> - level, optname, m0);
> - m = NULL; /* freed by protocol */
> + level, optname, m);
> }
> }
> -bad:
> - if (m)
> - (void) m_free(m);
> +
> return (error);
> }
>
> Index: kern/uipc_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
> retrieving revision 1.159
> diff -u -p -r1.159 uipc_syscalls.c
> --- kern/uipc_syscalls.c 22 Aug 2017 09:13:36 -0000 1.159
> +++ kern/uipc_syscalls.c 22 Aug 2017 15:12:58 -0000
> @@ -979,7 +979,6 @@ sys_setsockopt(struct proc *p, void *v,
> s = solock(so);
> error = sosetopt(so, SCARG(uap, level), SCARG(uap, name), m);
> sounlock(s);
> - m = NULL;
> bad:
> m_freem(m);
> FRELE(fp, p);
> Index: net/bfd.c
> ===================================================================
> RCS file: /cvs/src/sys/net/bfd.c,v
> retrieving revision 1.63
> diff -u -p -r1.63 bfd.c
> --- net/bfd.c 10 Aug 2017 16:38:37 -0000 1.63
> +++ net/bfd.c 22 Aug 2017 15:12:58 -0000
> @@ -454,6 +454,7 @@ bfd_listener(struct bfd_config *bfd, uns
> ip = mtod(mopt, int *);
> *ip = MAXTTL;
> error = sosetopt(so, IPPROTO_IP, IP_MINTTL, mopt);
> + m_freem(mopt);
> if (error) {
> printf("%s: sosetopt error %d\n",
> __func__, error);
> @@ -528,6 +529,7 @@ bfd_sender(struct bfd_config *bfd, unsig
> ip = mtod(mopt, int *);
> *ip = IP_PORTRANGE_HIGH;
> error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
> + m_freem(mopt);
> if (error) {
> printf("%s: sosetopt error %d\n",
> __func__, error);
> @@ -539,6 +541,7 @@ bfd_sender(struct bfd_config *bfd, unsig
> ip = mtod(mopt, int *);
> *ip = MAXTTL;
> error = sosetopt(so, IPPROTO_IP, IP_TTL, mopt);
> + m_freem(mopt);
> if (error) {
> printf("%s: sosetopt error %d\n",
> __func__, error);
> @@ -550,6 +553,7 @@ bfd_sender(struct bfd_config *bfd, unsig
> ip = mtod(mopt, int *);
> *ip = IPTOS_PREC_INTERNETCONTROL;
> error = sosetopt(so, IPPROTO_IP, IP_TOS, mopt);
> + m_freem(mopt);
> if (error) {
> printf("%s: sosetopt error %d\n",
> __func__, error);
> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.248
> diff -u -p -r1.248 rtsock.c
> --- net/rtsock.c 11 Aug 2017 21:24:19 -0000 1.248
> +++ net/rtsock.c 22 Aug 2017 15:12:58 -0000
> @@ -276,12 +276,8 @@ route_ctloutput(int op, struct socket *s
> int error = 0;
> unsigned int tid;
>
> - if (level != AF_ROUTE) {
> - error = EINVAL;
> - if (op == PRCO_SETOPT && m)
> - m_free(m);
> - return (error);
> - }
> + if (level != AF_ROUTE)
> + return (EINVAL);
>
> switch (op) {
> case PRCO_SETOPT:
> @@ -307,7 +303,6 @@ route_ctloutput(int op, struct socket *s
> error = ENOPROTOOPT;
> break;
> }
> - m_free(m);
> break;
> case PRCO_GETOPT:
> switch (optname) {
> Index: netinet/ip_mroute.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_mroute.c,v
> retrieving revision 1.120
> diff -u -p -r1.120 ip_mroute.c
> --- netinet/ip_mroute.c 26 Jun 2017 09:32:32 -0000 1.120
> +++ netinet/ip_mroute.c 22 Aug 2017 15:12:58 -0000
> @@ -216,7 +216,6 @@ ip_mrouter_set(struct socket *so, int op
> break;
> }
>
> - m_free(m);
> return (error);
> }
>
> Index: netinet/ip_output.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_output.c,v
> retrieving revision 1.340
> diff -u -p -r1.340 ip_output.c
> --- netinet/ip_output.c 29 May 2017 14:36:22 -0000 1.340
> +++ netinet/ip_output.c 1 Sep 2017 09:54:01 -0000
> @@ -72,6 +72,8 @@
> #endif
> #endif /* IPSEC */
>
> +int ip_pcbopts(struct mbuf **, struct mbuf *);
> +int ip_setmoptions(int, struct ip_moptions **, struct mbuf *, u_int);
> void ip_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in *);
> static __inline u_int16_t __attribute__((__unused__))
> in_cksum_phdr(u_int32_t, u_int32_t, u_int32_t);
> @@ -849,8 +851,6 @@ ip_ctloutput(int op, struct socket *so,
>
> if (level != IPPROTO_IP) {
> error = EINVAL;
> - if (op == PRCO_SETOPT)
> - (void) m_free(m);
> } else switch (op) {
> case PRCO_SETOPT:
> switch (optname) {
> @@ -1067,7 +1067,6 @@ ip_ctloutput(int op, struct socket *so,
> error = ENOPROTOOPT;
> break;
> }
> - m_free(m);
> break;
>
> case PRCO_GETOPT:
> @@ -1234,12 +1233,11 @@ ip_pcbopts(struct mbuf **pcbopt, struct
> /*
> * Only turning off any previous options.
> */
> - m_free(m);
> return (0);
> }
>
> if (m->m_len % sizeof(int32_t))
> - goto bad;
> + return (EINVAL);
>
> /*
> * IP first-hop destination address will be stored before
> @@ -1247,7 +1245,7 @@ ip_pcbopts(struct mbuf **pcbopt, struct
> * and clear it when none present.
> */
> if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN])
> - goto bad;
> + return (EINVAL);
> cnt = m->m_len;
> m->m_len += sizeof(struct in_addr);
> cp = mtod(m, u_char *) + sizeof(struct in_addr);
> @@ -1262,10 +1260,10 @@ ip_pcbopts(struct mbuf **pcbopt, struct
> optlen = 1;
> else {
> if (cnt < IPOPT_OLEN + sizeof(*cp))
> - goto bad;
> + return (EINVAL);
> optlen = cp[IPOPT_OLEN];
> if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt)
> - goto bad;
> + return (EINVAL);
> }
> switch (opt) {
>
> @@ -1283,7 +1281,7 @@ ip_pcbopts(struct mbuf **pcbopt, struct
> * actual IP option, but is stored before the options.
> */
> if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr))
> - goto bad;
> + return (EINVAL);
> m->m_len -= sizeof(struct in_addr);
> cnt -= sizeof(struct in_addr);
> optlen -= sizeof(struct in_addr);
> @@ -1305,13 +1303,12 @@ ip_pcbopts(struct mbuf **pcbopt, struct
> }
> }
> if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr))
> - goto bad;
> - *pcbopt = m;
> - return (0);
> + return (EINVAL);
> + *pcbopt = m_dup_pkt(m, 0, M_NOWAIT);
> + if (*pcbopt == NULL)
> + return (ENOBUFS);
>
> -bad:
> - (void)m_free(m);
> - return (EINVAL);
> + return (0);
> }
>
> /*
> Index: netinet/ip_var.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_var.h,v
> retrieving revision 1.80
> diff -u -p -r1.80 ip_var.h
> --- netinet/ip_var.h 14 Jul 2017 16:50:41 -0000 1.80
> +++ netinet/ip_var.h 22 Aug 2017 15:12:59 -0000
> @@ -230,13 +230,11 @@ int ip_mforward(struct mbuf *, struct i
> int ip_optcopy(struct ip *, struct ip *);
> int ip_output(struct mbuf *, struct mbuf *, struct route *, int,
> struct ip_moptions *, struct inpcb *, u_int32_t);
> -int ip_pcbopts(struct mbuf **, struct mbuf *);
> struct mbuf *
> ip_reass(struct ipqent *, struct ipq *);
> u_int16_t
> ip_randomid(void);
> void ip_send(struct mbuf *);
> -int ip_setmoptions(int, struct ip_moptions **, struct mbuf *, u_int);
> void ip_slowtimo(void);
> struct mbuf *
> ip_srcroute(struct mbuf *);
> Index: netinet/raw_ip.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/raw_ip.c,v
> retrieving revision 1.101
> diff -u -p -r1.101 raw_ip.c
> --- netinet/raw_ip.c 11 Aug 2017 19:53:02 -0000 1.101
> +++ netinet/raw_ip.c 22 Aug 2017 15:12:59 -0000
> @@ -301,11 +301,8 @@ rip_ctloutput(int op, struct socket *so,
> int error = 0;
> int dir;
>
> - if (level != IPPROTO_IP) {
> - if (op == PRCO_SETOPT)
> - (void) m_free(m);
> + if (level != IPPROTO_IP)
> return (EINVAL);
> - }
>
> switch (optname) {
>
> @@ -318,7 +315,6 @@ rip_ctloutput(int op, struct socket *so,
> inp->inp_flags |= INP_HDRINCL;
> else
> inp->inp_flags &= ~INP_HDRINCL;
> - m_free(m);
> } else {
> m->m_len = sizeof(int);
> *mtod(m, int *) = inp->inp_flags & INP_HDRINCL;
> @@ -353,8 +349,6 @@ rip_ctloutput(int op, struct socket *so,
> break;
> }
>
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
> return (error);
>
> case MRT_INIT:
> @@ -381,8 +375,6 @@ rip_ctloutput(int op, struct socket *so,
> }
> return (error);
> #else
> - if (op == PRCO_SETOPT)
> - m_free(m);
> return (EOPNOTSUPP);
> #endif
> }
> Index: netinet/tcp_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
> retrieving revision 1.153
> diff -u -p -r1.153 tcp_usrreq.c
> --- netinet/tcp_usrreq.c 15 Aug 2017 17:47:15 -0000 1.153
> +++ netinet/tcp_usrreq.c 22 Aug 2017 15:12:59 -0000
> @@ -437,11 +437,8 @@ tcp_ctloutput(int op, struct socket *so,
> int i;
>
> inp = sotoinpcb(so);
> - if (inp == NULL) {
> - if (op == PRCO_SETOPT)
> - (void) m_free(m);
> + if (inp == NULL)
> return (ECONNRESET);
> - }
> if (level != IPPROTO_TCP) {
> switch (so->so_proto->pr_domain->dom_family) {
> #ifdef INET6
> @@ -547,7 +544,6 @@ tcp_ctloutput(int op, struct socket *so,
> error = ENOPROTOOPT;
> break;
> }
> - m_free(m);
> break;
>
> case PRCO_GETOPT:
> Index: netinet6/icmp6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/icmp6.c,v
> retrieving revision 1.215
> diff -u -p -r1.215 icmp6.c
> --- netinet6/icmp6.c 10 Aug 2017 02:26:26 -0000 1.215
> +++ netinet6/icmp6.c 22 Aug 2017 15:12:59 -0000
> @@ -1687,11 +1687,8 @@ icmp6_ctloutput(int op, struct socket *s
> int error = 0;
> struct inpcb *in6p = sotoinpcb(so);
>
> - if (level != IPPROTO_ICMPV6) {
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
> + if (level != IPPROTO_ICMPV6)
> return EINVAL;
> - }
>
> switch (op) {
> case PRCO_SETOPT:
> @@ -1719,7 +1716,6 @@ icmp6_ctloutput(int op, struct socket *s
> error = ENOPROTOOPT;
> break;
> }
> - m_freem(m);
> break;
>
> case PRCO_GETOPT:
> Index: netinet6/ip6_output.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/ip6_output.c,v
> retrieving revision 1.231
> diff -u -p -r1.231 ip6_output.c
> --- netinet6/ip6_output.c 9 May 2017 09:32:21 -0000 1.231
> +++ netinet6/ip6_output.c 22 Aug 2017 15:12:59 -0000
> @@ -1045,11 +1045,8 @@ ip6_ctloutput(int op, struct socket *so,
> privileged = (inp->inp_socket->so_state & SS_PRIV);
> uproto = (int)so->so_proto->pr_protocol;
>
> - if (level != IPPROTO_IPV6) {
> - if (op == PRCO_SETOPT)
> - m_free(m);
> + if (level != IPPROTO_IPV6)
> return (EINVAL);
> - }
>
> switch (op) {
> case PRCO_SETOPT:
> @@ -1378,7 +1375,6 @@ do { \
> error = ENOPROTOOPT;
> break;
> }
> - m_free(m);
> break;
>
> case PRCO_GETOPT:
> @@ -1590,11 +1586,8 @@ ip6_raw_ctloutput(int op, struct socket
> const int icmp6off = offsetof(struct icmp6_hdr, icmp6_cksum);
> struct inpcb *inp = sotoinpcb(so);
>
> - if (level != IPPROTO_IPV6) {
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
> + if (level != IPPROTO_IPV6)
> return (EINVAL);
> - }
>
> switch (optname) {
> case IPV6_CHECKSUM:
> @@ -1643,9 +1636,6 @@ ip6_raw_ctloutput(int op, struct socket
> error = ENOPROTOOPT;
> break;
> }
> -
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
>
> return (error);
> }
> Index: netinet6/raw_ip6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v
> retrieving revision 1.117
> diff -u -p -r1.117 raw_ip6.c
> --- netinet6/raw_ip6.c 15 Aug 2017 17:47:15 -0000 1.117
> +++ netinet6/raw_ip6.c 22 Aug 2017 15:12:59 -0000
> @@ -525,8 +525,6 @@ rip6_ctloutput(int op, struct socket *so
> break;
> }
>
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
> return (error);
>
> #ifdef MROUTING
> @@ -538,7 +536,6 @@ rip6_ctloutput(int op, struct socket *so
> case MRT6_DEL_MFC:
> if (op == PRCO_SETOPT) {
> error = ip6_mrouter_set(optname, so, m);
> - m_free(m);
> } else if (op == PRCO_GETOPT)
> error = ip6_mrouter_get(optname, so, m);
> else
> @@ -559,8 +556,6 @@ rip6_ctloutput(int op, struct socket *so
> return (icmp6_ctloutput(op, so, level, optname, m));
>
> default:
> - if (op == PRCO_SETOPT)
> - m_free(m);
> return EINVAL;
> }
> }
> Index: sys/socketvar.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/socketvar.h,v
> retrieving revision 1.75
> diff -u -p -r1.75 socketvar.h
> --- sys/socketvar.h 22 Aug 2017 09:13:36 -0000 1.75
> +++ sys/socketvar.h 22 Aug 2017 15:12:59 -0000
> @@ -329,8 +329,7 @@ int soreserve(struct socket *so, u_long
> void sorflush(struct socket *so);
> int sosend(struct socket *so, struct mbuf *addr, struct uio *uio,
> struct mbuf *top, struct mbuf *control, int flags);
> -int sosetopt(struct socket *so, int level, int optname,
> - struct mbuf *m0);
> +int sosetopt(struct socket *so, int level, int optname, struct mbuf *m);
> int soshutdown(struct socket *so, int how);
> void sowakeup(struct socket *so, struct sockbuf *sb);
> void sorwakeup(struct socket *);
> Index: nfs/krpc_subr.c
> ===================================================================
> RCS file: /cvs/src/sys/nfs/krpc_subr.c,v
> retrieving revision 1.31
> diff -u -p -r1.31 krpc_subr.c
> --- nfs/krpc_subr.c 10 Aug 2017 19:20:43 -0000 1.31
> +++ nfs/krpc_subr.c 22 Aug 2017 15:12:59 -0000
> @@ -242,6 +242,7 @@ krpc_call(struct sockaddr_in *sa, u_int
> s = solock(so);
> error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m);
> sounlock(s);
> + m_freem(m);
> if (error)
> goto out;
>
> @@ -257,6 +258,7 @@ krpc_call(struct sockaddr_in *sa, u_int
> s = solock(so);
> error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m);
> sounlock(s);
> + m_freem(m);
> if (error)
> goto out;
> }
> @@ -273,6 +275,7 @@ krpc_call(struct sockaddr_in *sa, u_int
> s = solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
> sounlock(s);
> + m_freem(mopt);
> if (error)
> goto out;
>
> @@ -299,6 +302,7 @@ krpc_call(struct sockaddr_in *sa, u_int
> s = solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
> sounlock(s);
> + m_freem(mopt);
> if (error)
> goto out;
>
> Index: nfs/nfs_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/nfs/nfs_socket.c,v
> retrieving revision 1.125
> diff -u -p -r1.125 nfs_socket.c
> --- nfs/nfs_socket.c 14 Aug 2017 16:56:57 -0000 1.125
> +++ nfs/nfs_socket.c 22 Aug 2017 15:12:59 -0000
> @@ -270,6 +270,7 @@ nfs_connect(struct nfsmount *nmp, struct
> s = solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
> sounlock(s);
> + m_freem(mopt);
> if (error)
> goto bad;
>
> @@ -294,6 +295,7 @@ nfs_connect(struct nfsmount *nmp, struct
> s = solock(so);
> error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
> sounlock(s);
> + m_freem(mopt);
> if (error)
> goto bad;
> }
> @@ -358,12 +360,14 @@ nfs_connect(struct nfsmount *nmp, struct
> *mtod(m, int32_t *) = 1;
> m->m_len = sizeof(int32_t);
> sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m);
> + m_freem(m);
> }
> if (so->so_proto->pr_protocol == IPPROTO_TCP) {
> MGET(m, M_WAIT, MT_SOOPTS);
> *mtod(m, int32_t *) = 1;
> m->m_len = sizeof(int32_t);
> sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
> + m_freem(m);
> }
> sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
> sizeof (u_int32_t)) * 2;
> Index: nfs/nfs_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/nfs/nfs_syscalls.c,v
> retrieving revision 1.110
> diff -u -p -r1.110 nfs_syscalls.c
> --- nfs/nfs_syscalls.c 9 Aug 2017 14:22:58 -0000 1.110
> +++ nfs/nfs_syscalls.c 22 Aug 2017 15:12:59 -0000
> @@ -265,6 +265,7 @@ nfssvc_addsock(struct file *fp, struct m
> *mtod(m, int32_t *) = 1;
> m->m_len = sizeof(int32_t);
> sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m);
> + m_freem(m);
> }
> if (so->so_proto->pr_domain->dom_family == AF_INET &&
> so->so_proto->pr_protocol == IPPROTO_TCP) {
> @@ -272,6 +273,7 @@ nfssvc_addsock(struct file *fp, struct m
> *mtod(m, int32_t *) = 1;
> m->m_len = sizeof(int32_t);
> sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
> + m_freem(m);
> }
> so->so_rcv.sb_flags &= ~SB_NOINTR;
> so->so_rcv.sb_timeo = 0;