Browse Source

cbor: Packed struct to bypass unaligned stack

This can happen due to cast using buggy GCC on ARMv7

Credit to our shy french pal
pr/spi.typo
Matias Devenuta 7 years ago committed by Oleg Hahm
parent
commit
63bcccf43d
  1. 23
      sys/cbor/cbor.c

23
sys/cbor/cbor.c

@ -95,7 +95,20 @@
#define NAN (0.0/0.0)
#endif
/* pack to force aligned access on ARMv7 (buggy GCC) */
#pragma GCC diagnostic error "-Wcast-align"
typedef struct __attribute__((packed)) {
unsigned char u8;
union {
uint16_t u16;
uint32_t u32;
uint64_t u64;
} u;
} cast_align_u8_t;
#ifndef CBOR_NO_FLOAT
/**
* Convert float @p x to network format
*/
@ -345,15 +358,15 @@ static size_t decode_int(const cbor_stream_t *s, size_t offset, uint64_t *val)
break;
case 2:
*val = HTONS(*((uint16_t *)&in[1]));
*val = HTONS(((cast_align_u8_t *)in)->u.u16);
break;
case 4:
*val = HTONL(*((uint32_t *)&in[1]));
*val = HTONL(((cast_align_u8_t *)in)->u.u32);
break;
default:
*val = HTONLL(*((uint64_t *)&in[1]));
*val = HTONLL(((cast_align_u8_t *)in)->u.u64);
break;
}
@ -565,7 +578,7 @@ size_t cbor_deserialize_float(const cbor_stream_t *stream, size_t offset, float
unsigned char *data = &stream->data[offset];
if (*data == CBOR_FLOAT32) {
*val = ntohf(*(uint32_t *)(data + 1));
*val = ntohf(((cast_align_u8_t *)data)->u.u32);
return 5;
}
@ -594,7 +607,7 @@ size_t cbor_deserialize_double(const cbor_stream_t *stream, size_t offset, doubl
if (*data == CBOR_FLOAT64) {
CBOR_ENSURE_SIZE_READ(stream, offset + 9);
*val = ntohd(*(uint64_t *)(data + 1));
*val = ntohd(((cast_align_u8_t *)data)->u.u64);
return 9;
}

Loading…
Cancel
Save