Use a union and struct for padding in DtlsFragBucket

Zero length arrays are not allowed so `byte padding[0]` is not a valid member. Changed to use a union and struct instead.
This commit is contained in:
Juliusz Sosinowicz
2022-09-06 15:07:55 +02:00
parent 8bf3e0829e
commit 28895ed0cd
4 changed files with 59 additions and 59 deletions

View File

@@ -679,11 +679,11 @@ static int Dtls13DetectDisruption(WOLFSSL* ssl, word32 fragOffset)
peer retransmission) */ peer retransmission) */
if (ssl->dtls_rx_msg_list != NULL) { if (ssl->dtls_rx_msg_list != NULL) {
DtlsFragBucket* last = ssl->dtls_rx_msg_list->fragBucketList; DtlsFragBucket* last = ssl->dtls_rx_msg_list->fragBucketList;
while (last != NULL && last->next != NULL) while (last != NULL && last->m.m.next != NULL)
last = last->next; last = last->m.m.next;
/* Does this fragment start right after the last fragment we /* Does this fragment start right after the last fragment we
* have stored? */ * have stored? */
if (last != NULL && (last->offset + last->sz) != fragOffset) if (last != NULL && (last->m.m.offset + last->m.m.sz) != fragOffset)
return 1; return 1;
} }
else { else {

View File

@@ -8143,7 +8143,7 @@ void DtlsMsgDelete(DtlsMsg* item, void* heap)
if (item != NULL) { if (item != NULL) {
while (item->fragBucketList != NULL) { while (item->fragBucketList != NULL) {
DtlsFragBucket* next = item->fragBucketList->next; DtlsFragBucket* next = item->fragBucketList->m.m.next;
DtlsMsgDestroyFragBucket(item->fragBucketList, heap); DtlsMsgDestroyFragBucket(item->fragBucketList, heap);
item->fragBucketList = next; item->fragBucketList = next;
} }
@@ -8195,9 +8195,9 @@ static DtlsFragBucket* DtlsMsgCreateFragBucket(word32 offset, const byte* data,
DYNAMIC_TYPE_DTLS_FRAG); DYNAMIC_TYPE_DTLS_FRAG);
if (bucket != NULL) { if (bucket != NULL) {
XMEMSET(bucket, 0, sizeof(*bucket)); XMEMSET(bucket, 0, sizeof(*bucket));
bucket->next = NULL; bucket->m.m.next = NULL;
bucket->offset = offset; bucket->m.m.offset = offset;
bucket->sz = dataSz; bucket->m.m.sz = dataSz;
if (data != NULL) if (data != NULL)
XMEMCPY(bucket->buf, data, dataSz); XMEMCPY(bucket->buf, data, dataSz);
} }
@@ -8219,27 +8219,27 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg,
const byte* data, word32 dataSz, void* heap) const byte* data, word32 dataSz, void* heap)
{ {
word32 offsetEnd = offset + dataSz; word32 offsetEnd = offset + dataSz;
word32 newOffset = min(cur->offset, offset); word32 newOffset = min(cur->m.m.offset, offset);
word32 newOffsetEnd; word32 newOffsetEnd;
word32 newSz; word32 newSz;
word32 overlapSz = cur->sz; word32 overlapSz = cur->m.m.sz;
DtlsFragBucket** chosenBucket; DtlsFragBucket** chosenBucket;
DtlsFragBucket* newBucket; DtlsFragBucket* newBucket;
DtlsFragBucket* otherBucket; DtlsFragBucket* otherBucket;
byte combineNext = FALSE; byte combineNext = FALSE;
if (next != NULL && offsetEnd >= next->offset) if (next != NULL && offsetEnd >= next->m.m.offset)
combineNext = TRUE; combineNext = TRUE;
if (combineNext) if (combineNext)
newOffsetEnd = next->offset + next->sz; newOffsetEnd = next->m.m.offset + next->m.m.sz;
else else
newOffsetEnd = max(cur->offset + cur->sz, offsetEnd); newOffsetEnd = max(cur->m.m.offset + cur->m.m.sz, offsetEnd);
newSz = newOffsetEnd - newOffset; newSz = newOffsetEnd - newOffset;
/* Expand the larger bucket if data bridges the gap between cur and next */ /* Expand the larger bucket if data bridges the gap between cur and next */
if (!combineNext || cur->sz >= next->sz) { if (!combineNext || cur->m.m.sz >= next->m.m.sz) {
chosenBucket = &cur; chosenBucket = &cur;
otherBucket = next; otherBucket = next;
} }
@@ -8256,9 +8256,9 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg,
if (chosenBucket == &next) { if (chosenBucket == &next) {
/* Update the link */ /* Update the link */
DtlsFragBucket* beforeNext = cur; DtlsFragBucket* beforeNext = cur;
while (beforeNext->next != next) while (beforeNext->m.m.next != next)
beforeNext = beforeNext->next; beforeNext = beforeNext->m.m.next;
beforeNext->next = tmp; beforeNext->m.m.next = tmp;
} }
newBucket = *chosenBucket = tmp; newBucket = *chosenBucket = tmp;
} }
@@ -8266,10 +8266,10 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg,
if (combineNext) { if (combineNext) {
/* Put next first since it will always be at the end. Use memmove since /* Put next first since it will always be at the end. Use memmove since
* newBucket may be next. */ * newBucket may be next. */
XMEMMOVE(newBucket->buf + (next->offset - newOffset), next->buf, XMEMMOVE(newBucket->buf + (next->m.m.offset - newOffset), next->buf,
next->sz); next->m.m.sz);
/* memory after newOffsetEnd is already copied. Don't do extra work. */ /* memory after newOffsetEnd is already copied. Don't do extra work. */
newOffsetEnd = next->offset; newOffsetEnd = next->m.m.offset;
} }
if (newOffset == offset) { if (newOffset == offset) {
@@ -8282,16 +8282,16 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg,
else { else {
/* data -> cur. memcpy as much possible as its faster. */ /* data -> cur. memcpy as much possible as its faster. */
XMEMMOVE(newBucket->buf + dataSz, cur->buf, XMEMMOVE(newBucket->buf + dataSz, cur->buf,
cur->sz - (offsetEnd - cur->offset)); cur->m.m.sz - (offsetEnd - cur->m.m.offset));
XMEMCPY(newBucket->buf, data, dataSz); XMEMCPY(newBucket->buf, data, dataSz);
} }
} }
else { else {
/* cur -> data */ /* cur -> data */
word32 curOffsetEnd = cur->offset + cur->sz; word32 curOffsetEnd = cur->m.m.offset + cur->m.m.sz;
if (newBucket != cur) if (newBucket != cur)
XMEMCPY(newBucket->buf, cur->buf, cur->sz); XMEMCPY(newBucket->buf, cur->buf, cur->m.m.sz);
XMEMCPY(newBucket->buf + cur->sz, XMEMCPY(newBucket->buf + cur->m.m.sz,
data + (curOffsetEnd - offset), data + (curOffsetEnd - offset),
newOffsetEnd - curOffsetEnd); newOffsetEnd - curOffsetEnd);
} }
@@ -8299,36 +8299,36 @@ static DtlsFragBucket* DtlsMsgCombineFragBuckets(DtlsMsg* msg,
/* All buckets up to and including next (if combining) have to be free'd */ /* All buckets up to and including next (if combining) have to be free'd */
{ {
DtlsFragBucket* toFree = cur->next; DtlsFragBucket* toFree = cur->m.m.next;
while (toFree != next) { while (toFree != next) {
DtlsFragBucket* n = toFree->next; DtlsFragBucket* n = toFree->m.m.next;
overlapSz += toFree->sz; overlapSz += toFree->m.m.sz;
DtlsMsgDestroyFragBucket(toFree, heap); DtlsMsgDestroyFragBucket(toFree, heap);
msg->fragBucketListCount--; msg->fragBucketListCount--;
toFree = n; toFree = n;
} }
if (combineNext) { if (combineNext) {
newBucket->next = next->next; newBucket->m.m.next = next->m.m.next;
overlapSz += next->sz; overlapSz += next->m.m.sz;
DtlsMsgDestroyFragBucket(otherBucket, heap); DtlsMsgDestroyFragBucket(otherBucket, heap);
msg->fragBucketListCount--; msg->fragBucketListCount--;
} }
else { else {
newBucket->next = next; newBucket->m.m.next = next;
} }
} }
/* Adjust size in msg */ /* Adjust size in msg */
msg->bytesReceived += newSz - overlapSz; msg->bytesReceived += newSz - overlapSz;
newBucket->offset = newOffset; newBucket->m.m.offset = newOffset;
newBucket->sz = newSz; newBucket->m.m.sz = newSz;
return newBucket; return newBucket;
} }
static void DtlsMsgAssembleCompleteMessage(DtlsMsg* msg) static void DtlsMsgAssembleCompleteMessage(DtlsMsg* msg)
{ {
/* We have received all necessary fragments. Reconstruct the header. */ /* We have received all necessary fragments. Reconstruct the header. */
if (msg->fragBucketListCount != 1 || msg->fragBucketList->offset != 0 || if (msg->fragBucketListCount != 1 || msg->fragBucketList->m.m.offset != 0 ||
msg->fragBucketList->sz != msg->sz) { msg->fragBucketList->m.m.sz != msg->sz) {
WOLFSSL_MSG("Major error in fragment assembly logic"); WOLFSSL_MSG("Major error in fragment assembly logic");
return; return;
} }
@@ -8395,9 +8395,9 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte ty
DtlsFragBucket* prev = NULL; DtlsFragBucket* prev = NULL;
DtlsFragBucket* cur = msg->fragBucketList; DtlsFragBucket* cur = msg->fragBucketList;
byte done = 0; byte done = 0;
for (; cur != NULL; prev = cur, cur = cur->next) { for (; cur != NULL; prev = cur, cur = cur->m.m.next) {
word32 curOffset = cur->offset; word32 curOffset = cur->m.m.offset;
word32 curEnd = cur->offset + cur->sz; word32 curEnd = cur->m.m.offset + cur->m.m.sz;
if (fragOffset >= curOffset && fragOffsetEnd <= curEnd) { if (fragOffset >= curOffset && fragOffsetEnd <= curEnd) {
/* We already have this fragment */ /* We already have this fragment */
@@ -8417,13 +8417,14 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte ty
WOLFSSL_ERROR_VERBOSE(DTLS_TOO_MANY_FRAGMENTS_E); WOLFSSL_ERROR_VERBOSE(DTLS_TOO_MANY_FRAGMENTS_E);
return DTLS_TOO_MANY_FRAGMENTS_E; return DTLS_TOO_MANY_FRAGMENTS_E;
} }
prev->next = DtlsMsgCreateFragBucket(fragOffset, data, fragSz, heap); prev->m.m.next =
if (prev->next != NULL) { DtlsMsgCreateFragBucket(fragOffset, data, fragSz, heap);
if (prev->m.m.next != NULL) {
msg->bytesReceived += fragSz; msg->bytesReceived += fragSz;
msg->fragBucketListCount++; msg->fragBucketListCount++;
} }
} }
else if (prev == NULL && fragOffsetEnd < cur->offset) { else if (prev == NULL && fragOffsetEnd < cur->m.m.offset) {
/* This is the new first fragment we have received */ /* This is the new first fragment we have received */
if (msg->fragBucketListCount >= DTLS_FRAG_POOL_SZ) { if (msg->fragBucketListCount >= DTLS_FRAG_POOL_SZ) {
WOLFSSL_ERROR_VERBOSE(DTLS_TOO_MANY_FRAGMENTS_E); WOLFSSL_ERROR_VERBOSE(DTLS_TOO_MANY_FRAGMENTS_E);
@@ -8432,7 +8433,7 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte ty
msg->fragBucketList = DtlsMsgCreateFragBucket(fragOffset, data, msg->fragBucketList = DtlsMsgCreateFragBucket(fragOffset, data,
fragSz, heap); fragSz, heap);
if (msg->fragBucketList != NULL) { if (msg->fragBucketList != NULL) {
msg->fragBucketList->next = cur; msg->fragBucketList->m.m.next = cur;
msg->bytesReceived += fragSz; msg->bytesReceived += fragSz;
msg->fragBucketListCount++; msg->fragBucketListCount++;
} }
@@ -8443,12 +8444,12 @@ int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte ty
} }
else { else {
/* Find if this fragment overlaps with any more */ /* Find if this fragment overlaps with any more */
DtlsFragBucket* next = cur->next; DtlsFragBucket* next = cur->m.m.next;
DtlsFragBucket** prev_next = prev != NULL DtlsFragBucket** prev_next = prev != NULL
? &prev->next : &msg->fragBucketList; ? &prev->m.m.next : &msg->fragBucketList;
while (next != NULL && while (next != NULL &&
(next->offset + next->sz) <= fragOffsetEnd) (next->m.m.offset + next->m.m.sz) <= fragOffsetEnd)
next = next->next; next = next->m.m.next;
/* We can combine the buckets */ /* We can combine the buckets */
*prev_next = DtlsMsgCombineFragBuckets(msg, cur, next, *prev_next = DtlsMsgCombineFragBuckets(msg, cur, next,
fragOffset, data, fragSz, heap); fragOffset, data, fragSz, heap);

View File

@@ -57684,8 +57684,8 @@ static int DFB_TEST(WOLFSSL* ssl, word32 seq, word32 len, word32 f_offset,
DtlsFragBucket* fb; DtlsFragBucket* fb;
if (cur->fragBucketList == NULL) if (cur->fragBucketList == NULL)
return -800; return -800;
for (fb = cur->fragBucketList; fb != NULL; fb = fb->next) { for (fb = cur->fragBucketList; fb != NULL; fb = fb->m.m.next) {
if (XMEMCMP(fb->buf, msg + fb->offset, fb->sz) != 0) if (XMEMCMP(fb->buf, msg + fb->m.m.offset, fb->m.m.sz) != 0)
return -900; return -900;
} }
} }

View File

@@ -4439,20 +4439,19 @@ typedef struct DtlsRecordLayerHeader {
byte length[2]; byte length[2];
} DtlsRecordLayerHeader; } DtlsRecordLayerHeader;
/* Padding necessary to fit DTLS_HANDSHAKE_HEADER_SZ bytes before the buf member
* of the DtlsFragBucket struct. */
#define WOLFSSL_DTLS_FRAG_BUCKET_PADDING \
((DTLS_HANDSHAKE_HEADER_SZ > (sizeof(struct DtlsFragBucket*) + \
sizeof(word32) + sizeof(word32))) ? \
(DTLS_HANDSHAKE_HEADER_SZ - sizeof(struct DtlsFragBucket*) - \
sizeof(word32) - sizeof(word32)) : 0)
typedef struct DtlsFragBucket { typedef struct DtlsFragBucket {
struct DtlsFragBucket* next; /* m stands for meta */
word32 offset; union {
word32 sz; struct {
byte padding[WOLFSSL_DTLS_FRAG_BUCKET_PADDING]; struct DtlsFragBucket* next;
word32 offset;
word32 sz;
} m;
/* Make sure we have at least DTLS_HANDSHAKE_HEADER_SZ bytes before the
* buf so that we can reconstruct the header in the allocated
* DtlsFragBucket buffer. */
byte padding[DTLS_HANDSHAKE_HEADER_SZ];
} m;
byte buf[]; byte buf[];
/* Add new member initialization to CreateFragBucket */ /* Add new member initialization to CreateFragBucket */
} DtlsFragBucket; } DtlsFragBucket;