Fix for non-linear skb

This commit is contained in:
Iurii Egorov
2024-09-15 20:20:42 +03:00
committed by Iurii Egorov
parent 5fbaee7526
commit 4f60d10d21
3 changed files with 60 additions and 21 deletions

View File

@@ -0,0 +1,51 @@
diff --git receive.c receive.c
index b3e0040..e42006d 100644
--- receive.c
+++ receive.c
@@ -54,10 +54,9 @@ static size_t validate_header_len(struct sk_buff *skb, struct wg_device *wg)
return 0;
}
-void prepare_advanced_secured_message(struct sk_buff *skb, struct wg_device *wg)
+static void prepare_advanced_secured_message(struct sk_buff *skb, struct wg_device *wg)
{
- u32 assumed_type = SKB_TYPE_LE32(skb);
- u32 assumed_offset;
+ u32 assumed_type, assumed_offset;
if (wg->advanced_security_config.advanced_security) {
if (skb->len == MESSAGE_INITIATION_SIZE + wg->advanced_security_config.init_packet_junk_size) {
@@ -72,6 +71,11 @@ void prepare_advanced_secured_message(struct sk_buff *skb, struct wg_device *wg)
if (unlikely(assumed_offset <= 0) || unlikely(!pskb_may_pull(skb, assumed_offset)))
return;
+ if (skb_is_nonlinear(skb) && unlikely(skb_linearize(skb))) {
+ net_dbg_skb_ratelimited("%s: non-linear sk_buff from %pISpfsc could not be linearized, dropping packet\n",
+ wg->dev->name, skb);
+ return;
+ }
skb_pull(skb, assumed_offset);
diff --git send.c send.c
index d65e58b..d6c27f1 100644
--- send.c
+++ send.c
@@ -20,7 +20,7 @@
#include <net/udp.h>
#include <net/sock.h>
-u32 wg_get_random_u32_inclusive(u32 floor, u32 ceil)
+static u32 wg_get_random_u32_inclusive(u32 floor, u32 ceil)
{
u32 diff = ceil - floor + 1;
return floor + (get_random_u32() % diff);
@@ -68,7 +60,7 @@ static void wg_packet_send_handshake_initiation(struct wg_peer *peer)
kfree(buffer);
}
- net_dbg_ratelimited("%s: Initiation magic header: %llu\n",
+ net_dbg_ratelimited("%s: Initiation magic header: %u\n",
peer->device->dev->name,
peer->advanced_security ? wg->advanced_security_config.init_packet_magic_header :
MESSAGE_HANDSHAKE_INITIATION);

View File

@@ -54,10 +54,9 @@ static size_t validate_header_len(struct sk_buff *skb, struct wg_device *wg)
return 0;
}
void prepare_advanced_secured_message(struct sk_buff *skb, struct wg_device *wg)
static void prepare_advanced_secured_message(struct sk_buff *skb, struct wg_device *wg)
{
u32 assumed_type = SKB_TYPE_LE32(skb);
u32 assumed_offset;
u32 assumed_type, assumed_offset;
if (wg->advanced_security_config.advanced_security) {
if (skb->len == MESSAGE_INITIATION_SIZE + wg->advanced_security_config.init_packet_junk_size) {
@@ -72,14 +71,14 @@ void prepare_advanced_secured_message(struct sk_buff *skb, struct wg_device *wg)
if (unlikely(assumed_offset <= 0) || unlikely(!pskb_may_pull(skb, assumed_offset)))
return;
net_dbg_skb_ratelimited("%s: Likely received handshake packet from %pISpfsc, assuming its type %l with offset %l (current type %l)\n",
wg->dev->name, skb, assumed_type, assumed_offset, SKB_TYPE_LE32(skb));
if (skb_is_nonlinear(skb) && unlikely(skb_linearize(skb))) {
net_dbg_skb_ratelimited("%s: non-linear sk_buff from %pISpfsc could not be linearized, dropping packet\n",
wg->dev->name, skb);
return;
}
skb_pull(skb, assumed_offset);
net_dbg_skb_ratelimited("%s: Packet from %pISpfsc real type after skb_pull %l\n",
wg->dev->name, skb, SKB_TYPE_LE32(skb));
if (SKB_TYPE_LE32(skb) != assumed_type) {
skb_push(skb, assumed_offset);
}

View File

@@ -20,7 +20,7 @@
#include <net/udp.h>
#include <net/sock.h>
u32 wg_get_random_u32_inclusive(u32 floor, u32 ceil)
static u32 wg_get_random_u32_inclusive(u32 floor, u32 ceil)
{
u32 diff = ceil - floor + 1;
return floor + (get_random_u32() % diff);
@@ -47,19 +47,11 @@ static void wg_packet_send_handshake_initiation(struct wg_peer *peer)
junk_packet_count = wg->advanced_security_config.junk_packet_count;
buffer = kzalloc(wg->advanced_security_config.junk_packet_max_size, GFP_KERNEL);
net_dbg_ratelimited("%s: Sending %llu junk packets to peer %llu (%pISpfsc)\n",
peer->device->dev->name, junk_packet_count, peer->internal_id,
&peer->endpoint.addr);
while (junk_packet_count-- > 0) {
junk_packet_size = (u16) wg_get_random_u32_inclusive(
wg->advanced_security_config.junk_packet_min_size,
wg->advanced_security_config.junk_packet_max_size);
net_dbg_ratelimited("%s: Sending %llu size junk packet to peer %llu (%pISpfsc)\n",
peer->device->dev->name, junk_packet_size, peer->internal_id,
&peer->endpoint.addr);
get_random_bytes(buffer, junk_packet_size);
get_random_bytes(&ds, 1);
wg_socket_send_buffer_to_peer(peer, buffer, junk_packet_size, ds);
@@ -68,7 +60,7 @@ static void wg_packet_send_handshake_initiation(struct wg_peer *peer)
kfree(buffer);
}
net_dbg_ratelimited("%s: Initiation magic header: %llu\n",
net_dbg_ratelimited("%s: Initiation magic header: %u\n",
peer->device->dev->name,
peer->advanced_security ? wg->advanced_security_config.init_packet_magic_header :
MESSAGE_HANDSHAKE_INITIATION);
@@ -82,9 +74,6 @@ static void wg_packet_send_handshake_initiation(struct wg_peer *peer)
ktime_get_coarse_boottime_ns());
if (wg->advanced_security_config.advanced_security && peer->advanced_security) {
net_dbg_ratelimited("%s: Initiation junked packet: %llu\n",
peer->device->dev->name, wg->advanced_security_config.init_packet_junk_size);
wg_socket_send_junked_buffer_to_peer(peer, &packet, sizeof(packet),
HANDSHAKE_DSCP, wg->advanced_security_config.init_packet_junk_size);
} else {