Fix mic calculation when final data is entirely in a trailing mbuf;

it's unclear if this can happen on freebsd but does appear on netbsd.
Identified by Matthias Drochner who came up with an initial change
that we then revised together.

Reviewed by:	thompsa, sephe, avatar
MFC after:	2 weeks
This commit is contained in:
Sam Leffler 2008-08-29 05:02:10 +00:00
parent b574dd8dd1
commit 02a1ebb4e3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=182434

View File

@ -831,7 +831,17 @@ michael_mic(struct tkip_ctx *ctx, const u8 *key,
data += sizeof(uint32_t), space -= sizeof(uint32_t);
data_len -= sizeof(uint32_t);
}
if (data_len < sizeof(uint32_t))
/*
* NB: when space is zero we make one more trip around
* the loop to advance to the next mbuf where there is
* data. This handles the case where there are 4*n
* bytes in an mbuf followed by <4 bytes in a later mbuf.
* By making an extra trip we'll drop out of the loop
* with m pointing at the mbuf with 3 bytes and space
* set as required by the remainder handling below.
*/
if (data_len == 0 ||
(data_len < sizeof(uint32_t) && space != 0))
break;
m = m->m_next;
if (m == NULL) {
@ -878,6 +888,14 @@ michael_mic(struct tkip_ctx *ctx, const u8 *key,
space = m->m_len;
}
}
/*
* Catch degenerate cases like mbuf[4*n+1 bytes] followed by
* mbuf[2 bytes]. I don't believe these should happen; if they
* do then we'll need more involved logic.
*/
KASSERT(data_len <= space,
("not enough data, data_len %u space %u\n", data_len, space));
/* Last block and padding (0x5a, 4..7 x 0) */
switch (data_len) {
case 0: