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) */
if (ssl->dtls_rx_msg_list != NULL) {
DtlsFragBucket* last = ssl->dtls_rx_msg_list->fragBucketList;
while (last != NULL && last->next != NULL)
last = last->next;
while (last != NULL && last->m.m.next != NULL)
last = last->m.m.next;
/* Does this fragment start right after the last fragment we
* have stored? */
if (last != NULL && (last->offset + last->sz) != fragOffset)
if (last != NULL && (last->m.m.offset + last->m.m.sz) != fragOffset)
return 1;
}
else {

View File

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

View File

@@ -4439,20 +4439,19 @@ typedef struct DtlsRecordLayerHeader {
byte length[2];
} 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 {
struct DtlsFragBucket* next;
word32 offset;
word32 sz;
byte padding[WOLFSSL_DTLS_FRAG_BUCKET_PADDING];
/* m stands for meta */
union {
struct {
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[];
/* Add new member initialization to CreateFragBucket */
} DtlsFragBucket;