summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2022-06-29 22:45:25 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2022-06-29 22:45:25 +0000
commitfe9a63ceb48a65b64d3f7e369e1bef324d4873ae (patch)
tree4a5fbe899ee32f671ba6a56219ba54c044272020 /sys
parentfc4b61e2bcc0fb04a7c76fa23419092be753926b (diff)
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@
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet6/dest6.c13
-rw-r--r--sys/netinet6/ip6_input.c48
-rw-r--r--sys/netinet6/ip6_output.c4
-rw-r--r--sys/netinet6/ip6_var.h6
4 files changed, 36 insertions, 35 deletions
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);