summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-08-03 18:02:08 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2020-08-04 16:29:07 +0200
commit4588e2e817ac17edb1526fca89aa09b6f1649fb0 (patch)
treea363e85e59c64b2814ac68cc333800ba275bb865
parent18c76745f6bdc310bb6139ef8425bc6ed7109908 (diff)
downloadNetworkManager-4588e2e817ac17edb1526fca89aa09b6f1649fb0.tar.gz
n-dhcp4: fix BPF filter endianness issue
The BPF filter takes the byte containing IP Flags and performs a bitwise AND with "ntohs(IP_MF | IP_OFFMASK)". On little-endian architectures the IP_MF flag (0x20) is ANDed with 0xFF3F and so the presence of the flag is correctly detected ignoring other flags as IP_DF (0x40) or IP_RF (0x80). On big-endian, "ntohs(IP_MF | IP_OFFMASK)" is 0x3FFF and so the filter wrongly checks the presence of *any* flags. Therefore, a packet with the DF flag set is dropped. Instead, take the two bytes containing flags and offset: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ and verify that IP_MF and the offset are zero. Fixes: e43b1791a382 ('Merge commit 'e23b3c9c3ac86b065eef002fa5c4321cc4a87df2' as 'shared/n-dhcp4'') https://bugzilla.redhat.com/show_bug.cgi?id=1861488 https://github.com/nettools/n-dhcp4/pull/19 (cherry picked from commit 03d38e83e558802a82cb0e4847cb1f1ef75ccd16) (cherry picked from commit 0024cef23850e6141a15cb02d92551adef3cf4dd) (cherry picked from commit 80835f8f8991ae8292790826afa3a5fc88b44d1a)
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-socket.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/shared/n-dhcp4/src/n-dhcp4-socket.c b/shared/n-dhcp4/src/n-dhcp4-socket.c
index c7e897726e..7291c78036 100644
--- a/shared/n-dhcp4/src/n-dhcp4-socket.c
+++ b/shared/n-dhcp4/src/n-dhcp4-socket.c
@@ -50,8 +50,8 @@ int n_dhcp4_c_socket_packet_new(int *sockfdp, int ifindex) {
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0), /* IP protocol == UDP ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(struct iphdr, frag_off)), /* A <- Flags */
- BPF_STMT(BPF_ALU + BPF_AND + BPF_K, ntohs(IP_MF | IP_OFFMASK)), /* A <- A & (IP_MF | IP_OFFMASK) */
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct iphdr, frag_off)), /* A <- Flags + Fragment offset */
+ BPF_STMT(BPF_ALU + BPF_AND + BPF_K, IP_MF | IP_OFFMASK), /* A <- A & (IP_MF | IP_OFFMASK) */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* fragmented packet ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */