mirror of
https://github.com/openvswitch/ovs
synced 2025-09-04 00:05:15 +00:00
byte-order: Fix undefined behavior of BYTES_TO_BE32.
A left shift that would produce a result that is not representable by the type of the expression's result has "undefined behavior" according to the C language standard. Avoid this by casting values that could set the upper bit to unsigned types. Also document and convert a macro to a function. While we're at it, delete the unused macro BE16S_TO_BE32. Found via gcc's undefined behavior sanitizer. Reported-by: Lance Richardson <lrichard@redhat.com> Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Lance Richardson <lrichard@redhat.com>
This commit is contained in:
@@ -98,17 +98,22 @@ uint32_byteswap(uint32_t crc) {
|
|||||||
((((ovs_be64) (VALUE)) & UINT64_C(0xff00000000000000)) >> 56))
|
((((ovs_be64) (VALUE)) & UINT64_C(0xff00000000000000)) >> 56))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Returns the ovs_be32 that you would get from:
|
||||||
|
*
|
||||||
|
* union { uint8_t b[4]; ovs_be32 be32; } x = { .b = { b0, b1, b2, b3 } };
|
||||||
|
* return x.be32;
|
||||||
|
*
|
||||||
|
* but without the undefined behavior. */
|
||||||
|
static inline ovs_be32
|
||||||
|
bytes_to_be32(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3)
|
||||||
|
{
|
||||||
#if WORDS_BIGENDIAN
|
#if WORDS_BIGENDIAN
|
||||||
#define BYTES_TO_BE32(B1, B2, B3, B4) \
|
uint32_t x = ((uint32_t) b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||||
(OVS_FORCE ovs_be32)((uint32_t)(B1) << 24 | (B2) << 16 | (B3) << 8 | (B4))
|
|
||||||
#define BE16S_TO_BE32(B1, B2) \
|
|
||||||
(OVS_FORCE ovs_be32)((uint32_t)(B1) << 16 | (B2))
|
|
||||||
#else
|
#else
|
||||||
#define BYTES_TO_BE32(B1, B2, B3, B4) \
|
uint32_t x = ((uint32_t) b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
|
||||||
(OVS_FORCE ovs_be32)((uint32_t)(B1) | (B2) << 8 | (B3) << 16 | (B4) << 24)
|
|
||||||
#define BE16S_TO_BE32(B1, B2) \
|
|
||||||
(OVS_FORCE ovs_be32)((uint32_t)(B1) | (B2) << 16)
|
|
||||||
#endif
|
#endif
|
||||||
|
return (OVS_FORCE ovs_be32) x;
|
||||||
|
}
|
||||||
|
|
||||||
/* These functions zero-extend big-endian values to longer ones,
|
/* These functions zero-extend big-endian values to longer ones,
|
||||||
* or truncate long big-endian value to shorter ones. */
|
* or truncate long big-endian value to shorter ones. */
|
||||||
|
@@ -823,7 +823,7 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst)
|
|||||||
|
|
||||||
packet->l4_ofs = (char *)data - frame;
|
packet->l4_ofs = (char *)data - frame;
|
||||||
miniflow_push_be32(mf, nw_frag,
|
miniflow_push_be32(mf, nw_frag,
|
||||||
BYTES_TO_BE32(nw_frag, nw_tos, nw_ttl, nw_proto));
|
bytes_to_be32(nw_frag, nw_tos, nw_ttl, nw_proto));
|
||||||
|
|
||||||
if (OVS_LIKELY(!(nw_frag & FLOW_NW_FRAG_LATER))) {
|
if (OVS_LIKELY(!(nw_frag & FLOW_NW_FRAG_LATER))) {
|
||||||
if (OVS_LIKELY(nw_proto == IPPROTO_TCP)) {
|
if (OVS_LIKELY(nw_proto == IPPROTO_TCP)) {
|
||||||
|
Reference in New Issue
Block a user