-/* $OpenBSD: if_iwm.c,v 1.231 2018/08/13 15:05:31 stsp Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.232 2018/09/16 19:41:45 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
struct ifnet *ifp = IC2IFP(ic);
struct iwm_rx_packet *pkt;
struct iwm_rx_mpdu_res_start *rx_res;
- uint32_t len;
+ uint16_t len;
uint32_t rx_pkt_status;
int rxfail;
m_freem(m);
return;
}
- if (len > maxlen) {
+ if (len + sizeof(*rx_res) + sizeof(rx_pkt_status) > maxlen ||
+ len > IEEE80211_MAX_LEN) {
IC2IFP(ic)->if_ierrors++;
m_freem(m);
return;
}
- rx_pkt_status = le32toh(*(uint32_t *)(pkt->data +
- sizeof(*rx_res) + len));
+ memcpy(&rx_pkt_status, pkt->data + sizeof(*rx_res) + len,
+ sizeof(rx_pkt_status));
+ rx_pkt_status = le32toh(rx_pkt_status);
rxfail = ((rx_pkt_status & IWM_RX_MPDU_RES_STATUS_CRC_OK) == 0 ||
(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_OVERRUN_OK) == 0);
if (rxfail) {
struct iwm_rx_packet *pkt;
uint32_t offset = 0, nmpdu = 0, len;
struct mbuf *m0;
- const uint32_t minsz = sizeof(uint32_t) + sizeof(struct iwm_cmd_header);
+ const size_t minsz = sizeof(pkt->len_n_flags) + sizeof(pkt->hdr);
int qid, idx, code;
bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
break;
}
- len = le32toh(pkt->len_n_flags) & IWM_FH_RSCSR_FRAME_SIZE_MSK;
- if (len < sizeof(struct iwm_cmd_header) ||
- len > (IWM_RBUF_SIZE - offset))
+ len = iwm_rx_packet_len(pkt);
+ if (len < sizeof(pkt->hdr) ||
+ len > (IWM_RBUF_SIZE - offset - minsz))
break;
- len += sizeof(uint32_t); /* account for status word */
if (code == IWM_REPLY_RX_MPDU_CMD && ++nmpdu == 1) {
/* Take mbuf m0 off the RX ring. */
}
m_adj(m, offset);
- iwm_rx_mpdu(sc, m, IWM_RBUF_SIZE - offset);
+ iwm_rx_mpdu(sc, m, IWM_RBUF_SIZE - offset - minsz);
break;
}
iwm_cmd_done(sc, pkt);
}
+ len += sizeof(pkt->len_n_flags);
offset += roundup(len, IWM_FH_RSCSR_FRAME_ALIGN);
}