summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2021-07-19 19:00:59 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2021-07-19 19:00:59 +0000
commitee8e393fcab6aae13554dfe7670edf2e47ba2ecf (patch)
treeec95907d5242b9f67ca752e2820c70f7e6aca2ab /sys
parent87e3023cde8db7a794e2896d66ffaafc727c752f (diff)
Fix an alignment fault observed on an octeon machine while pppoe(4) was
attempting to negotiate a large MTU. Copy the peer's max payload size from the discovery packet with memcpy() instead of using a pointer to this value's offset in the packet buffer. tweak and ok visa@ additional testing and ok sthen@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_pppoe.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/sys/net/if_pppoe.c b/sys/net/if_pppoe.c
index a31b3e3f4fe..36cd5a30689 100644
--- a/sys/net/if_pppoe.c
+++ b/sys/net/if_pppoe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pppoe.c,v 1.77 2021/01/19 19:38:29 mvs Exp $ */
+/* $OpenBSD: if_pppoe.c,v 1.78 2021/07/19 19:00:58 stsp Exp $ */
/* $NetBSD: if_pppoe.c,v 1.51 2003/11/28 08:56:48 keihan Exp $ */
/*
@@ -347,8 +347,8 @@ pppoe_dispatch_disc_pkt(struct mbuf *m)
const char *err_msg, *devname;
size_t ac_cookie_len;
size_t relay_sid_len;
- int off, noff, err, errortag;
- u_int16_t *max_payload;
+ int off, noff, err, errortag, max_payloadtag;
+ u_int16_t max_payload;
u_int16_t tag, len;
u_int16_t session, plen;
u_int8_t *ac_cookie;
@@ -359,6 +359,7 @@ pppoe_dispatch_disc_pkt(struct mbuf *m)
devname = "pppoe";
off = 0;
errortag = 0;
+ max_payloadtag = 0;
if (m->m_len < sizeof(*eh)) {
m = m_pullup(m, sizeof(*eh));
@@ -372,7 +373,7 @@ pppoe_dispatch_disc_pkt(struct mbuf *m)
ac_cookie_len = 0;
relay_sid = NULL;
relay_sid_len = 0;
- max_payload = NULL;
+ max_payload = 0;
session = 0;
if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) {
@@ -473,15 +474,17 @@ pppoe_dispatch_disc_pkt(struct mbuf *m)
}
break;
case PPPOE_TAG_MAX_PAYLOAD:
- if (max_payload == NULL) {
+ if (!max_payloadtag) {
n = m_pulldown(m, off, len,
&noff);
- if (n == NULL || len != 2) {
+ if (n == NULL || len != sizeof(max_payload)) {
err_msg = "TAG MAX_PAYLOAD ERROR";
m = NULL;
break;
}
- max_payload = (u_int16_t *)(mtod(n, caddr_t) + noff);
+ memcpy(&max_payload, mtod(n, caddr_t) + noff,
+ sizeof(max_payload));
+ max_payloadtag = 1;
}
break;
case PPPOE_TAG_SNAME_ERR:
@@ -556,8 +559,8 @@ breakbreak:
memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len);
}
if (sc->sc_sppp.pp_if.if_mtu > PPPOE_MTU &&
- (max_payload == NULL ||
- ntohs(*max_payload) != sc->sc_sppp.pp_if.if_mtu)) {
+ (!max_payloadtag ||
+ ntohs(max_payload) != sc->sc_sppp.pp_if.if_mtu)) {
printf("%s: No valid PPP-Max-Payload tag received in PADO\n",
sc->sc_sppp.pp_if.if_xname);
sc->sc_sppp.pp_if.if_mtu = PPPOE_MTU;