Blame SOURCES/1006-n-dhcp4-fix-bpf-for-big-endian-arch-rh1861488.patch

f25c7b
From ab260205b54bf3ae4862c11a2d47b84ff6cebe24 Mon Sep 17 00:00:00 2001
f25c7b
From: Beniamino Galvani <bgalvani@redhat.com>
f25c7b
Date: Mon, 3 Aug 2020 18:02:08 +0200
f25c7b
Subject: [PATCH 1/1] n-dhcp4: fix BPF filter endianness issue
f25c7b
f25c7b
The BPF filter takes the byte containing IP Flags and performs a
f25c7b
bitwise AND with "ntohs(IP_MF | IP_OFFMASK)".
f25c7b
f25c7b
On little-endian architectures the IP_MF flag (0x20) is ANDed with
f25c7b
0xFF3F and so the presence of the flag is correctly detected ignoring
f25c7b
other flags as IP_DF (0x40) or IP_RF (0x80).
f25c7b
f25c7b
On big-endian, "ntohs(IP_MF | IP_OFFMASK)" is 0x3FFF and so the filter
f25c7b
wrongly checks the presence of *any* flags. Therefore, a packet with
f25c7b
the DF flag set is dropped.
f25c7b
f25c7b
Instead, take the two bytes containing flags and offset:
f25c7b
f25c7b
    0                   1                   2                   3
f25c7b
    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
f25c7b
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
f25c7b
   |Version|  IHL  |Type of Service|          Total Length         |
f25c7b
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
f25c7b
   |         Identification        |Flags|      Fragment Offset    |
f25c7b
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
f25c7b
f25c7b
and verify that IP_MF and the offset are zero.
f25c7b
f25c7b
Fixes: e43b1791a382 ('Merge commit 'e23b3c9c3ac86b065eef002fa5c4321cc4a87df2' as 'shared/n-dhcp4'')
f25c7b
f25c7b
https://bugzilla.redhat.com/show_bug.cgi?id=1861488
f25c7b
https://github.com/nettools/n-dhcp4/pull/19
f25c7b
(cherry picked from commit 03d38e83e558802a82cb0e4847cb1f1ef75ccd16)
f25c7b
(cherry picked from commit 0024cef23850e6141a15cb02d92551adef3cf4dd)
f25c7b
(cherry picked from commit 80835f8f8991ae8292790826afa3a5fc88b44d1a)
f25c7b
---
f25c7b
 shared/n-dhcp4/src/n-dhcp4-socket.c | 4 ++--
f25c7b
 1 file changed, 2 insertions(+), 2 deletions(-)
f25c7b
f25c7b
diff --git a/shared/n-dhcp4/src/n-dhcp4-socket.c b/shared/n-dhcp4/src/n-dhcp4-socket.c
f25c7b
index c7e897726ef8..7291c78036bc 100644
f25c7b
--- a/shared/n-dhcp4/src/n-dhcp4-socket.c
f25c7b
+++ b/shared/n-dhcp4/src/n-dhcp4-socket.c
f25c7b
@@ -50,8 +50,8 @@ int n_dhcp4_c_socket_packet_new(int *sockfdp, int ifindex) {
f25c7b
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0),                                         /* IP protocol == UDP ? */
f25c7b
                 BPF_STMT(BPF_RET + BPF_K, 0),                                                                   /* ignore */
f25c7b
 
f25c7b
-                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(struct iphdr, frag_off)),                           /* A <- Flags */
f25c7b
-                BPF_STMT(BPF_ALU + BPF_AND + BPF_K, ntohs(IP_MF | IP_OFFMASK)),                                 /* A <- A & (IP_MF | IP_OFFMASK) */
f25c7b
+                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct iphdr, frag_off)),                           /* A <- Flags + Fragment offset */
f25c7b
+                BPF_STMT(BPF_ALU + BPF_AND + BPF_K, IP_MF | IP_OFFMASK),                                        /* A <- A & (IP_MF | IP_OFFMASK) */
f25c7b
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0),                                                   /* fragmented packet ? */
f25c7b
                 BPF_STMT(BPF_RET + BPF_K, 0),                                                                   /* ignore */
f25c7b
 
f25c7b
-- 
f25c7b
2.26.2
f25c7b