dhcp: Fix destination port check in packet filter
authorTobias Brunner <tobias@strongswan.org>
Fri, 16 Mar 2018 08:59:25 +0000 (09:59 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 18 May 2018 16:04:01 +0000 (18:04 +0200)
The previous code compared the port in the packet to the client port and, if
successful, checked it also against the server port, which, therefore, never
matched, but due to incorrect offsets did skip the BPF_JA.  If the client port
didn't match the code also skipped to the instruction after the BPF_JA.
However, the latter was incorrect also and processing would have continued at
the next instruction anyway.  Basically, DHCP packets to any port were accepted.

What's not fixed with this is that the kernel returns an ICMP Port
unreachable for packets sent to the server port (67) because we don't
have a socket bound to it.

Fixes: f0212e8837b5 ("Accept DHCP replies on bootps port, as we act as a relay agent if server address configured")

src/libcharon/plugins/dhcp/dhcp_socket.c

index 7541c3b..02aa298 100644 (file)
@@ -685,9 +685,9 @@ dhcp_socket_t *dhcp_socket_create()
                BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, DHCP_SERVER_PORT, 0, 14),
                BPF_STMT(BPF_LD+BPF_H+BPF_ABS, sizeof(struct iphdr) +
                                 offsetof(struct udphdr, dest)),
-               BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, DHCP_CLIENT_PORT, 0, 2),
-               BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, DHCP_SERVER_PORT, 0, 1),
-               BPF_JUMP(BPF_JMP+BPF_JA, 0, 0, 10),
+               BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, DHCP_CLIENT_PORT, 2, 0),
+               BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, DHCP_SERVER_PORT, 1, 0),
+               BPF_JUMP(BPF_JMP+BPF_JA, 10, 0, 0),
                BPF_STMT(BPF_LD+BPF_B+BPF_ABS, sizeof(struct iphdr) +
                                 sizeof(struct udphdr) + offsetof(dhcp_t, opcode)),
                BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, BOOTREPLY, 0, 8),