mirror of
https://github.com/samba-team/samba.git
synced 2025-02-08 05:57:51 +03:00
ctdb-common: Fix aliasing issue in IPv6 checksum
Since commit 9c51b278b1700cd5f3e2addc19b7c711cc2ea10b the compiler has been able to inline the affected call to uint16_checksum(). Given that the data (phdr) is being accessed by an incompatible pointer (data) there is an aliasing problem when the call is inlined. This results in incorrect behaviour with -O2/-O3 when compiling with at least GCC 6, 7, and 8. Fix this by making the types compatible. Also fixes CID 1437604 (Reliance on integer endianness). This is a false positive because the uint16_checksum doesn't depend on the order of the input uint16_t items. https://bugzilla.samba.org/show_bug.cgi?id=13588 Pair-programmed-with: Amitay Isaacs <amitay@gmail.com> Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com> (cherry picked from commit 48335725deecdbdb24a9176cf31e9611c9deda49)
This commit is contained in:
parent
3fd839aeba
commit
7e38e9503a
@ -270,16 +270,20 @@ static uint16_t ip_checksum(uint16_t *data, size_t n, struct ip *ip)
|
||||
|
||||
static uint16_t ip6_checksum(uint16_t *data, size_t n, struct ip6_hdr *ip6)
|
||||
{
|
||||
uint32_t phdr[2];
|
||||
uint16_t phdr[3];
|
||||
uint32_t sum = 0;
|
||||
uint16_t sum2;
|
||||
uint32_t len;
|
||||
|
||||
sum += uint16_checksum((uint16_t *)(void *)&ip6->ip6_src, 16);
|
||||
sum += uint16_checksum((uint16_t *)(void *)&ip6->ip6_dst, 16);
|
||||
|
||||
phdr[0] = htonl(n);
|
||||
phdr[1] = htonl(ip6->ip6_nxt);
|
||||
sum += uint16_checksum((uint16_t *)phdr, 8);
|
||||
len = htonl(n);
|
||||
phdr[0] = len & UINT16_MAX;
|
||||
phdr[1] = (len >> 16) & UINT16_MAX;
|
||||
/* ip6_nxt is only 8 bits, so fits comfortably into a uint16_t */
|
||||
phdr[2] = htons(ip6->ip6_nxt);
|
||||
sum += uint16_checksum(phdr, sizeof(phdr));
|
||||
|
||||
sum += uint16_checksum(data, n);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user