From: bluhm Date: Wed, 29 Jun 2022 22:45:24 +0000 (+0000) Subject: Pass a pointer to mbuf pointer further down into ip6_process_hopopts() X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=80467c39870d6dd5a679fab4a36d2a744bf98ed1;p=openbsd Pass a pointer to mbuf pointer further down into ip6_process_hopopts() and ip6_unknown_opt(). Instead of having dangling pointer in caller, use m_freemp() to set mbuf to NULL. OK sashan@ --- diff --git a/sys/netinet6/dest6.c b/sys/netinet6/dest6.c index e6e88644d6b..edd22339589 100644 --- a/sys/netinet6/dest6.c +++ b/sys/netinet6/dest6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dest6.c,v 1.18 2022/02/22 01:15:02 guenther Exp $ */ +/* $OpenBSD: dest6.c,v 1.19 2022/06/29 22:45:24 bluhm Exp $ */ /* $KAME: dest6.c,v 1.25 2001/02/22 01:39:16 itojun Exp $ */ /* @@ -49,18 +49,17 @@ int dest6_input(struct mbuf **mp, int *offp, int proto, int af) { - struct mbuf *m = *mp; int off = *offp, dstoptlen, optlen; struct ip6_dest *dstopts; u_int8_t *opt; /* validation of the length of the header */ - IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, sizeof(*dstopts)); + IP6_EXTHDR_GET(dstopts, struct ip6_dest *, *mp, off, sizeof(*dstopts)); if (dstopts == NULL) return IPPROTO_DONE; dstoptlen = (dstopts->ip6d_len + 1) << 3; - IP6_EXTHDR_GET(dstopts, struct ip6_dest *, m, off, dstoptlen); + IP6_EXTHDR_GET(dstopts, struct ip6_dest *, *mp, off, dstoptlen); if (dstopts == NULL) return IPPROTO_DONE; off += dstoptlen; @@ -83,8 +82,8 @@ dest6_input(struct mbuf **mp, int *offp, int proto, int af) optlen = *(opt + 1) + 2; break; default: /* unknown option */ - optlen = ip6_unknown_opt(opt, m, - opt - mtod(m, u_int8_t *)); + optlen = ip6_unknown_opt(mp, opt, + opt - mtod(*mp, u_int8_t *)); if (optlen == -1) return (IPPROTO_DONE); optlen += 2; @@ -96,6 +95,6 @@ dest6_input(struct mbuf **mp, int *offp, int proto, int af) return (dstopts->ip6d_nxt); bad: - m_freem(m); + m_freemp(mp); return (IPPROTO_DONE); } diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index dcaad09338b..2fa634927ad 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.247 2022/06/29 11:22:10 bluhm Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.248 2022/06/29 22:45:24 bluhm Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -123,7 +123,7 @@ int ip6_ours(struct mbuf **, int *, int, int); int ip6_local(struct mbuf **, int *, int, int); int ip6_check_rh0hdr(struct mbuf *, int *); int ip6_hbhchcheck(struct mbuf **, int *, int *); -int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); +int ip6_hopopts_input(struct mbuf **, int *, u_int32_t *, u_int32_t *); struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); int ip6_sysctl_soiikey(void *, size_t *, void *, size_t); @@ -616,7 +616,7 @@ ip6_hbhchcheck(struct mbuf **mp, int *offp, int *oursp) if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { struct ip6_hbh *hbh; - if (ip6_hopopts_input(&plen, &rtalert, mp, offp)) + if (ip6_hopopts_input(mp, offp, &plen, &rtalert)) goto bad; /* m have already been freed */ /* adjust pointer */ @@ -758,8 +758,8 @@ ip6_check_rh0hdr(struct mbuf *m, int *offp) * rtalertp - XXX: should be stored in a more smart way */ int -ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, struct mbuf **mp, - int *offp) +ip6_hopopts_input(struct mbuf **mp, int *offp, u_int32_t *plenp, + u_int32_t *rtalertp) { int off = *offp, hbhlen; struct ip6_hbh *hbh; @@ -781,7 +781,7 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, struct mbuf **mp, off += hbhlen; hbhlen -= sizeof(struct ip6_hbh); - if (ip6_process_hopopts(*mp, (u_int8_t *)hbh + sizeof(struct ip6_hbh), + if (ip6_process_hopopts(mp, (u_int8_t *)hbh + sizeof(struct ip6_hbh), hbhlen, rtalertp, plenp) < 0) return (-1); @@ -794,13 +794,14 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, struct mbuf **mp, * This function is separate from ip6_hopopts_input() in order to * handle a case where the sending node itself process its hop-by-hop * options header. In such a case, the function is called from ip6_output(). + * On error free mbuf and return -1. * * The function assumes that hbh header is located right after the IPv6 header * (RFC2460 p7), opthead is pointer into data content in m, and opthead to * opthead + hbhlen is located in continuous memory region. */ int -ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, +ip6_process_hopopts(struct mbuf **mp, u_int8_t *opthead, int hbhlen, u_int32_t *rtalertp, u_int32_t *plenp) { struct ip6_hdr *ip6; @@ -830,7 +831,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, } if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) { /* XXX stat */ - icmp6_error(m, ICMP6_PARAM_PROB, + icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, erroff + opt + 1 - opthead); return (-1); @@ -847,7 +848,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, } if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) { /* XXX stat */ - icmp6_error(m, ICMP6_PARAM_PROB, + icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, erroff + opt + 1 - opthead); return (-1); @@ -858,10 +859,10 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, * IPv6 packets that have non 0 payload length * must not contain a jumbo payload option. */ - ip6 = mtod(m, struct ip6_hdr *); + ip6 = mtod(*mp, struct ip6_hdr *); if (ip6->ip6_plen) { ip6stat_inc(ip6s_badoptions); - icmp6_error(m, ICMP6_PARAM_PROB, + icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, erroff + opt - opthead); return (-1); @@ -885,7 +886,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, */ if (*plenp != 0) { ip6stat_inc(ip6s_badoptions); - icmp6_error(m, ICMP6_PARAM_PROB, + icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, erroff + opt + 2 - opthead); return (-1); @@ -897,7 +898,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, */ if (jumboplen <= IPV6_MAXPACKET) { ip6stat_inc(ip6s_badoptions); - icmp6_error(m, ICMP6_PARAM_PROB, + icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, erroff + opt + 2 - opthead); return (-1); @@ -910,7 +911,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, ip6stat_inc(ip6s_toosmall); goto bad; } - optlen = ip6_unknown_opt(opt, m, + optlen = ip6_unknown_opt(mp, opt, erroff + opt - opthead); if (optlen == -1) return (-1); @@ -922,7 +923,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, return (0); bad: - m_freem(m); + m_freemp(mp); return (-1); } @@ -931,9 +932,10 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, * The third argument `off' is the offset from the IPv6 header to the option, * which allows returning an ICMPv6 error even if the IPv6 header and the * option header are not continuous. + * On error free mbuf and return -1. */ int -ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off) +ip6_unknown_opt(struct mbuf **mp, u_int8_t *optp, int off) { struct ip6_hdr *ip6; @@ -941,25 +943,25 @@ ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off) case IP6OPT_TYPE_SKIP: /* ignore the option */ return ((int)*(optp + 1)); case IP6OPT_TYPE_DISCARD: /* silently discard */ - m_freem(m); + m_freemp(mp); return (-1); case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ ip6stat_inc(ip6s_badoptions); - icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); + icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); return (-1); case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ ip6stat_inc(ip6s_badoptions); - ip6 = mtod(m, struct ip6_hdr *); + ip6 = mtod(*mp, struct ip6_hdr *); if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || - (m->m_flags & (M_BCAST|M_MCAST))) - m_freem(m); + ((*mp)->m_flags & (M_BCAST|M_MCAST))) + m_freemp(mp); else - icmp6_error(m, ICMP6_PARAM_PROB, + icmp6_error(*mp, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); return (-1); } - m_freem(m); /* XXX: NOTREACHED */ + m_freemp(mp); /* XXX: NOTREACHED */ return (-1); } diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 1fa8996a534..8fbac583874 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.268 2022/02/22 01:35:41 guenther Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.269 2022/06/29 22:45:24 bluhm Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -619,7 +619,7 @@ reroute: u_int32_t plen = 0; /* no more than 1 jumbo payload option! */ m->m_pkthdr.ph_ifidx = ifp->if_index; - if (ip6_process_hopopts(m, (u_int8_t *)(hbh + 1), + if (ip6_process_hopopts(&m, (u_int8_t *)(hbh + 1), ((hbh->ip6h_len + 1) << 3) - sizeof(struct ip6_hbh), &rtalert, &plen) < 0) { /* m was already freed at this point */ diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 1fa3297b883..9ea94ff8eb2 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_var.h,v 1.92 2022/05/05 13:57:41 claudio Exp $ */ +/* $OpenBSD: ip6_var.h,v 1.93 2022/06/29 22:45:24 bluhm Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* @@ -307,12 +307,12 @@ void ip6intr(void); int ip6_input_if(struct mbuf **, int *, int, int, struct ifnet *); void ip6_freepcbopts(struct ip6_pktopts *); void ip6_freemoptions(struct ip6_moptions *); -int ip6_unknown_opt(u_int8_t *, struct mbuf *, int); +int ip6_unknown_opt(struct mbuf **, u_int8_t *, int); int ip6_get_prevhdr(struct mbuf *, int); int ip6_nexthdr(struct mbuf *, int, int, int *); int ip6_lasthdr(struct mbuf *, int, int, int *); int ip6_mforward(struct ip6_hdr *, struct ifnet *, struct mbuf *); -int ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *, +int ip6_process_hopopts(struct mbuf **, u_int8_t *, int, u_int32_t *, u_int32_t *); void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **); int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);