Netdev List
 help / color / mirror / Atom feed
* [PATCH net] tipc: raise the minimum bearer MTU to fit tunnel and crypto overhead
@ 2026-10-09 12:53 Joas Antonio dos Santos
  2026-10-12 15:56 ` Tung Quang Nguyen
  0 siblings, 1 reply; 4+ messages in thread
From: Joas Antonio dos Santos @ 2026-10-09 12:53 UTC (permalink / raw)
  To: Jon Maloy, Tung Quang Nguyen
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, netdev, tipc-discussion

A peer can lower the link MTU to TIPC_MIN_BEARER_MTU (100 bytes, plus
the UDP encapsulation header) with the max_pkt field of a RESET or
ACTIVATE message; tipc_link_proto_rcv() only checks the lower bound
returned by tipc_bearer_min_mtu().  The same bound is applied to the
device MTU when a bearer is enabled.

That bound predates two later reductions of the link MSS:

  tipc_link_mss() = mtu - INT_H_SIZE                    (tunnel header)
                         - EMSG_OVERHEAD               (CONFIG_TIPC_CRYPTO)

With CONFIG_TIPC_CRYPTO=y, which is the default, an MTU of 100 gives an
MSS of 28.  Once the link comes up, tipc_named_node_up() calls
named_distribute(), which computes

  msg_dsz = ((tipc_node_get_mtu() - INT_H_SIZE) / ITEM_SIZE) * ITEM_SIZE;

For an MSS of 28 the subtraction is negative and the result truncates to
0xfffffff0; for an MSS between 40 and 59 it is 0.  named_prepare_buf()
then allocates a buffer with no room for any item (the u32 size wraps),
and msg_rem never reaches zero, so every cluster-scope publication on
the node is written with publ_to_item() past the end of that one skb,
over skb_shared_info and into adjacent memory.

Without crypto the MSS is at least 60, which still does not hold the
first fragment built by tipc_msg_build(): INT_H_SIZE fragment header
plus a message header of up to MAX_H_SIZE.  With pktmax below that, the
header copies run past the pktmax bytes allocated for the fragment.

Raise the minimum so the MSS can always hold INT_H_SIZE + MAX_H_SIZE,
which also leaves room for name table items: MAX_H_SIZE + 2 * INT_H_SIZE,
plus EMSG_OVERHEAD when crypto is enabled.  EMSG_OVERHEAD is defined in
crypto.h, which bearer.h cannot include, so the value is spelled out and
checked with BUILD_BUG_ON() in tipc_bearer_min_mtu().

Found by manual code review, assisted by an LLM, and reproduced with
KASAN using two network namespaces joined by a veth pair (see below).

Fixes: fc1b6d6de220 ("tipc: introduce TIPC encryption & authentication")
Fixes: 2320bcdae628 ("tipc: fix changeover issues due to large packet")
Signed-off-by: Joas Antonio dos Santos <joasantonio108@gmail.com>
Assisted-by: Claude:claude-opus-5-5
---
Reproduced on 602042bf29f6 (arm64, QEMU, KASAN, CONFIG_TIPC_CRYPTO=y)
with two network namespaces joined by a veth pair.  Node A binds 40
cluster-scope services, node B enables its bearer on a veth with MTU 100,
so A negotiates a link MTU of 100 (a remote peer can do the same with
max_pkt=100 in RESET/ACTIVATE).  As soon as the link comes up:

  BUG: KASAN: slab-out-of-bounds in publ_to_item+0x23c/0x288
  Write of size 4 at addr fff000001036ad00 by task ksoftirqd/1/22
   publ_to_item+0x23c/0x288
   tipc_named_node_up+0x2b0/0x714
   tipc_node_write_unlock+0x330/0x44c
   tipc_rcv+0x94c/0x2188
   tipc_l2_rcv_msg+0x118/0x1f4
  Allocated by task 22:
   ...
   tipc_buf_acquire+0x24/0xd4
   named_prepare_buf+0x3c/0x1dc
   tipc_named_node_up+0x528/0x714
  The buggy address is located 0 bytes to the right of
   allocated 704-byte region [fff000001036aa40, fff000001036ad00)
  tipc: Too large msg, purging xmit list 1 11 0 860 100!
  Unable to handle kernel paging request at virtual address 001fe000022e18a9
  pc : kfree_skb_list_reason+0xa4/0x32c

The final oops is the purge freeing the frag_list pointer that the
overflow wrote into skb_shared_info.

With the patch: MTU 100 is refused at bearer enable ("MTU too low for
tipc bearer"); MTU 172 and 1500 bring the link up with no KASAN report.
Builds cleanly with W=1 with and without CONFIG_TIPC_CRYPTO.
This was first reported to security@kernel.org; Tung Nguyen reproduced
it with the reproducer below and asked for the patch to go to netdev.

Reproducer (as root, CONFIG_TIPC=y, CONFIG_TIPC_CRYPTO=y; build with
"gcc -Wall -O2 -o pub pub.c", run "sh tipc_repro.sh"):

pub.c:

  /* Bind N TIPC services with cluster scope, then sleep. */
  #include <linux/tipc.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <sys/socket.h>
  #include <unistd.h>

  int main(int argc, char **argv)
  {
  	int n = argc > 1 ? atoi(argv[1]) : 40;
  	for (int i = 0; i < n; i++) {
  		struct sockaddr_tipc a = {
  			.family = AF_TIPC,
  			.addrtype = TIPC_SERVICE_RANGE,
  			.scope = TIPC_CLUSTER_SCOPE,
  			.addr.nameseq = { .type = 1000 + i, .lower = 0, .upper = 0 },
  		};
  		int s = socket(AF_TIPC, SOCK_RDM, 0);
  		if (s < 0 || bind(s, (struct sockaddr *)&a, sizeof(a))) {
  			perror("tipc bind");
  			return 1;
  		}
  	}
  	printf("pub: bound %d cluster-scope services\n", n);
  	fflush(stdout);
  	pause();
  	return 0;
  }

tipc_repro.sh:

  #!/bin/sh
  # TIPC named_distribute() overflow reproducer.
  # Needs root, CONFIG_TIPC=y, CONFIG_TIPC_CRYPTO=y (default), KASAN recommended.
  # Usage: ./tipc_repro.sh [peer_mtu]   (default 100; 100..131 trigger it)
  PEER_MTU=${1:-100}

  ip netns add A
  ip netns add B
  ip link add va type veth peer name vb
  ip link set va netns A
  ip link set vb netns B
  ip -n A link set lo up
  ip -n B link set lo up
  ip -n A link set va mtu 1500 up
  ip -n B link set vb mtu "$PEER_MTU" up

  # node A: 40 cluster-scope publications (any number >= 1 overflows;
  # more publications write further past the buffer)
  ip netns exec A ./pub 40 &
  sleep 2

  # node A uses MTU 1500, node B uses PEER_MTU; the link MTU is
  # negotiated down to PEER_MTU, the link MSS becomes PEER_MTU - 72
  ip netns exec A tipc bearer enable media eth dev va
  ip netns exec B tipc bearer enable media eth dev vb

  # the overflow happens in tipc_named_node_up() as soon as the link
  # comes up (a few seconds)
  sleep 20
  dmesg | grep -A30 -E "KASAN|BUG:|Oops"

This edits the lines next to the ones touched by Yunpeng Tian's
"tipc: bound the device MTU accepted ..." (upper bound, posted
2026-10-03).  The two are independent; I can rebase on top of it if
that one is applied first.

tipc_msg_build() / named_distribute() could also get local sanity
checks; I kept this to the MTU floor so there is one fix point.

 net/tipc/bearer.c |  4 ++++
 net/tipc/bearer.h | 16 ++++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 05dcd2f9e..bcf031fdd 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -549,6 +549,10 @@ int tipc_bearer_min_mtu(struct net *net, u32 bearer_id)
 	int mtu = TIPC_MIN_BEARER_MTU;
 	struct tipc_bearer *b;
 
+#ifdef CONFIG_TIPC_CRYPTO
+	BUILD_BUG_ON(TIPC_MIN_BEARER_MTU !=
+		     MAX_H_SIZE + 2 * INT_H_SIZE + EMSG_OVERHEAD);
+#endif
 	rcu_read_lock();
 	b = bearer_get(net, bearer_id);
 	if (b)
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 41eac1ee0..b99dcd23c 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -60,8 +60,20 @@
 #define TIPC_MEDIA_TYPE_IB	2
 #define TIPC_MEDIA_TYPE_UDP	3
 
-/* Minimum bearer MTU */
-#define TIPC_MIN_BEARER_MTU	(MAX_H_SIZE + INT_H_SIZE)
+/* Minimum bearer MTU
+ *
+ * The link MSS (see tipc_link_mss()) is the MTU minus a tunnel header
+ * (INT_H_SIZE) and, with encryption, minus EMSG_OVERHEAD (32 bytes, checked
+ * in tipc_bearer_min_mtu()).  The MSS must still hold a fragment header
+ * (INT_H_SIZE) followed by the largest message header (MAX_H_SIZE), which is
+ * what tipc_msg_build() puts in the first fragment, and leaves room for at
+ * least one name table item in named_distribute().
+ */
+#ifdef CONFIG_TIPC_CRYPTO
+#define TIPC_MIN_BEARER_MTU	(MAX_H_SIZE + 2 * INT_H_SIZE + 32)
+#else
+#define TIPC_MIN_BEARER_MTU	(MAX_H_SIZE + 2 * INT_H_SIZE)
+#endif
 
 /* Identifiers for distinguishing between broadcast/multicast and replicast
  */

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* RE: [PATCH net] tipc: raise the minimum bearer MTU to fit tunnel and crypto overhead
  2026-10-09 12:53 [PATCH net] tipc: raise the minimum bearer MTU to fit tunnel and crypto overhead Joas Antonio dos Santos
@ 2026-10-12 15:56 ` Tung Quang Nguyen
  2026-10-12 19:52   ` Joas Antonio dos Santos
  0 siblings, 1 reply; 4+ messages in thread
From: Tung Quang Nguyen @ 2026-10-12 15:56 UTC (permalink / raw)
  To: Joas Antonio dos Santos
  Cc: David S.Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, netdev@vger.kernel.org,
	tipc-discussion@lists.sourceforge.net, Jon Maloy

>Subject: [PATCH net] tipc: raise the minimum bearer MTU to fit tunnel and
>crypto overhead
>
>A peer can lower the link MTU to TIPC_MIN_BEARER_MTU (100 bytes, plus the
>UDP encapsulation header) with the max_pkt field of a RESET or ACTIVATE
>message; tipc_link_proto_rcv() only checks the lower bound returned by
>tipc_bearer_min_mtu().  The same bound is applied to the device MTU when a
>bearer is enabled.
>
>That bound predates two later reductions of the link MSS:
>
>  tipc_link_mss() = mtu - INT_H_SIZE                    (tunnel header)
>                         - EMSG_OVERHEAD               (CONFIG_TIPC_CRYPTO)
>
>With CONFIG_TIPC_CRYPTO=y, which is the default, an MTU of 100 gives an
>MSS of 28.  Once the link comes up, tipc_named_node_up() calls
>named_distribute(), which computes
>
>  msg_dsz = ((tipc_node_get_mtu() - INT_H_SIZE) / ITEM_SIZE) * ITEM_SIZE;
>
>For an MSS of 28 the subtraction is negative and the result truncates to
>0xfffffff0; for an MSS between 40 and 59 it is 0.  named_prepare_buf() then
>allocates a buffer with no room for any item (the u32 size wraps), and
>msg_rem never reaches zero, so every cluster-scope publication on the node is
>written with publ_to_item() past the end of that one skb, over
>skb_shared_info and into adjacent memory.
>
>Without crypto the MSS is at least 60, which still does not hold the first
>fragment built by tipc_msg_build(): INT_H_SIZE fragment header plus a
>message header of up to MAX_H_SIZE.  With pktmax below that, the header
>copies run past the pktmax bytes allocated for the fragment.
>
>Raise the minimum so the MSS can always hold INT_H_SIZE + MAX_H_SIZE,
>which also leaves room for name table items: MAX_H_SIZE + 2 * INT_H_SIZE,
>plus EMSG_OVERHEAD when crypto is enabled.  EMSG_OVERHEAD is defined
>in crypto.h, which bearer.h cannot include, so the value is spelled out and
>checked with BUILD_BUG_ON() in tipc_bearer_min_mtu().
>
>Found by manual code review, assisted by an LLM, and reproduced with KASAN
>using two network namespaces joined by a veth pair (see below).
>
>Fixes: fc1b6d6de220 ("tipc: introduce TIPC encryption & authentication")
>Fixes: 2320bcdae628 ("tipc: fix changeover issues due to large packet")
>Signed-off-by: Joas Antonio dos Santos <joasantonio108@gmail.com>
>Assisted-by: Claude:claude-opus-5-5
>---
>Reproduced on 602042bf29f6 (arm64, QEMU, KASAN,
>CONFIG_TIPC_CRYPTO=y) with two network namespaces joined by a veth pair.
>Node A binds 40 cluster-scope services, node B enables its bearer on a veth
>with MTU 100, so A negotiates a link MTU of 100 (a remote peer can do the
>same with
>max_pkt=100 in RESET/ACTIVATE).  As soon as the link comes up:
>
>  BUG: KASAN: slab-out-of-bounds in publ_to_item+0x23c/0x288
>  Write of size 4 at addr fff000001036ad00 by task ksoftirqd/1/22
>   publ_to_item+0x23c/0x288
>   tipc_named_node_up+0x2b0/0x714
>   tipc_node_write_unlock+0x330/0x44c
>   tipc_rcv+0x94c/0x2188
>   tipc_l2_rcv_msg+0x118/0x1f4
>  Allocated by task 22:
>   ...
>   tipc_buf_acquire+0x24/0xd4
>   named_prepare_buf+0x3c/0x1dc
>   tipc_named_node_up+0x528/0x714
>  The buggy address is located 0 bytes to the right of
>   allocated 704-byte region [fff000001036aa40, fff000001036ad00)
>  tipc: Too large msg, purging xmit list 1 11 0 860 100!
>  Unable to handle kernel paging request at virtual address 001fe000022e18a9
>  pc : kfree_skb_list_reason+0xa4/0x32c
>
>The final oops is the purge freeing the frag_list pointer that the overflow wrote
>into skb_shared_info.
>
>With the patch: MTU 100 is refused at bearer enable ("MTU too low for tipc
>bearer"); MTU 172 and 1500 bring the link up with no KASAN report.
>Builds cleanly with W=1 with and without CONFIG_TIPC_CRYPTO.
>This was first reported to security@kernel.org; Tung Nguyen reproduced it with
>the reproducer below and asked for the patch to go to netdev.
>
>Reproducer (as root, CONFIG_TIPC=y, CONFIG_TIPC_CRYPTO=y; build with "gcc
>-Wall -O2 -o pub pub.c", run "sh tipc_repro.sh"):
>
>pub.c:
>
>  /* Bind N TIPC services with cluster scope, then sleep. */
>  #include <linux/tipc.h>
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <sys/socket.h>
>  #include <unistd.h>
>
>  int main(int argc, char **argv)
>  {
>  	int n = argc > 1 ? atoi(argv[1]) : 40;
>  	for (int i = 0; i < n; i++) {
>  		struct sockaddr_tipc a = {
>  			.family = AF_TIPC,
>  			.addrtype = TIPC_SERVICE_RANGE,
>  			.scope = TIPC_CLUSTER_SCOPE,
>  			.addr.nameseq = { .type = 1000 + i, .lower = 0, .upper =
>0 },
>  		};
>  		int s = socket(AF_TIPC, SOCK_RDM, 0);
>  		if (s < 0 || bind(s, (struct sockaddr *)&a, sizeof(a))) {
>  			perror("tipc bind");
>  			return 1;
>  		}
>  	}
>  	printf("pub: bound %d cluster-scope services\n", n);
>  	fflush(stdout);
>  	pause();
>  	return 0;
>  }
>
>tipc_repro.sh:
>
>  #!/bin/sh
>  # TIPC named_distribute() overflow reproducer.
>  # Needs root, CONFIG_TIPC=y, CONFIG_TIPC_CRYPTO=y (default), KASAN
>recommended.
>  # Usage: ./tipc_repro.sh [peer_mtu]   (default 100; 100..131 trigger it)
>  PEER_MTU=${1:-100}
>
>  ip netns add A
>  ip netns add B
>  ip link add va type veth peer name vb
>  ip link set va netns A
>  ip link set vb netns B
>  ip -n A link set lo up
>  ip -n B link set lo up
>  ip -n A link set va mtu 1500 up
>  ip -n B link set vb mtu "$PEER_MTU" up
>
>  # node A: 40 cluster-scope publications (any number >= 1 overflows;
>  # more publications write further past the buffer)
>  ip netns exec A ./pub 40 &
>  sleep 2
>
>  # node A uses MTU 1500, node B uses PEER_MTU; the link MTU is
>  # negotiated down to PEER_MTU, the link MSS becomes PEER_MTU - 72
>  ip netns exec A tipc bearer enable media eth dev va
>  ip netns exec B tipc bearer enable media eth dev vb
>
>  # the overflow happens in tipc_named_node_up() as soon as the link
>  # comes up (a few seconds)
>  sleep 20
>  dmesg | grep -A30 -E "KASAN|BUG:|Oops"
>
>This edits the lines next to the ones touched by Yunpeng Tian's
>"tipc: bound the device MTU accepted ..." (upper bound, posted 2026-10-03).
>The two are independent; I can rebase on top of it if that one is applied first.
>
>tipc_msg_build() / named_distribute() could also get local sanity checks; I kept
>this to the MTU floor so there is one fix point.
>
> net/tipc/bearer.c |  4 ++++
> net/tipc/bearer.h | 16 ++++++++++++++--
> 2 files changed, 18 insertions(+), 2 deletions(-)
>
>diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 05dcd2f9e..bcf031fdd
>100644
>--- a/net/tipc/bearer.c
>+++ b/net/tipc/bearer.c
>@@ -549,6 +549,10 @@ int tipc_bearer_min_mtu(struct net *net, u32
>bearer_id)
> 	int mtu = TIPC_MIN_BEARER_MTU;
> 	struct tipc_bearer *b;
>
>+#ifdef CONFIG_TIPC_CRYPTO
>+	BUILD_BUG_ON(TIPC_MIN_BEARER_MTU !=
>+		     MAX_H_SIZE + 2 * INT_H_SIZE + EMSG_OVERHEAD); #endif
> 	rcu_read_lock();
> 	b = bearer_get(net, bearer_id);
> 	if (b)
>diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 41eac1ee0..b99dcd23c
>100644
>--- a/net/tipc/bearer.h
>+++ b/net/tipc/bearer.h
>@@ -60,8 +60,20 @@
> #define TIPC_MEDIA_TYPE_IB	2
> #define TIPC_MEDIA_TYPE_UDP	3
>
>-/* Minimum bearer MTU */
>-#define TIPC_MIN_BEARER_MTU	(MAX_H_SIZE + INT_H_SIZE)
>+/* Minimum bearer MTU
>+ *
>+ * The link MSS (see tipc_link_mss()) is the MTU minus a tunnel header
>+ * (INT_H_SIZE) and, with encryption, minus EMSG_OVERHEAD (32 bytes,
>+checked
>+ * in tipc_bearer_min_mtu()).  The MSS must still hold a fragment
>+header
>+ * (INT_H_SIZE) followed by the largest message header (MAX_H_SIZE),
>+which is
>+ * what tipc_msg_build() puts in the first fragment, and leaves room
>+for at
>+ * least one name table item in named_distribute().
>+ */
>+#ifdef CONFIG_TIPC_CRYPTO
>+#define TIPC_MIN_BEARER_MTU	(MAX_H_SIZE + 2 * INT_H_SIZE + 32)

This approach is not good because  it uses hard-coded size of TIPC crypto header (32).
The size should be calculated based on tipc_ehdr.
Could you please test below general approach ?

---
 net/tipc/bearer.c    | 16 ++++++++++++++++
 net/tipc/bearer.h    |  2 +-
 net/tipc/crypto.h    | 19 +++++++++++++++++++
 net/tipc/udp_media.h | 10 ++++++++--
 4 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 05dcd2f9e887..02b2e9f56cc5 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -433,7 +433,11 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
        dev = dev_get_by_name(net, dev_name);
        if (!dev)
                return -ENODEV;
+#ifdef CONFIG_TIPC_CRYPTO
+       if (tipc_mtu_bad_crypto(dev)) {
+#else
        if (tipc_mtu_bad(dev)) {
+#endif
                dev_put(dev);
                return -EINVAL;
        }
@@ -546,7 +550,11 @@ int tipc_bearer_mtu(struct net *net, u32 bearer_id)

 int tipc_bearer_min_mtu(struct net *net, u32 bearer_id)
 {
+#ifdef CONFIG_TIPC_CRYPTO
+       int mtu = TIPC_MIN_BEARER_MTU_CRYPTO;
+#else
        int mtu = TIPC_MIN_BEARER_MTU;
+#endif
        struct tipc_bearer *b;

        rcu_read_lock();
@@ -711,7 +719,11 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
                test_and_set_bit_lock(0, &b->up);
                break;
        case NETDEV_CHANGEMTU:
+#ifdef CONFIG_TIPC_CRYPTO
+               if (tipc_mtu_bad_crypto(dev)) {
+#else
                if (tipc_mtu_bad(dev)) {
+#endif
                        bearer_disable(net, b);
                        break;
                }
@@ -1158,7 +1170,11 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
                        }
 #ifdef CONFIG_TIPC_MEDIA_UDP
                        if (nla_get_u32(props[TIPC_NLA_PROP_MTU]) <
+#ifdef CONFIG_TIPC_CRYPTO
+                           b->encap_hlen + TIPC_MIN_BEARER_MTU_CRYPTO) {
+#else
                            b->encap_hlen + TIPC_MIN_BEARER_MTU) {
+#endif
                                NL_SET_ERR_MSG(info->extack,
                                               "MTU value is out-of-range");
                                return -EINVAL;
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 41eac1ee0c09..1bf629f2e626 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -61,7 +61,7 @@
 #define TIPC_MEDIA_TYPE_UDP    3

 /* Minimum bearer MTU */
-#define TIPC_MIN_BEARER_MTU    (MAX_H_SIZE + INT_H_SIZE)
+#define TIPC_MIN_BEARER_MTU    (MAX_H_SIZE + 2 * INT_H_SIZE)

 /* Identifiers for distinguishing between broadcast/multicast and replicast
  */
diff --git a/net/tipc/crypto.h b/net/tipc/crypto.h
index ce7d4cc8a9e0..1d5a4839d639 100644
--- a/net/tipc/crypto.h
+++ b/net/tipc/crypto.h
@@ -156,6 +156,8 @@ struct tipc_ehdr {
 #define EMSG_OVERHEAD  (EHDR_SIZE + TIPC_AES_GCM_TAG_SIZE)
 } __packed;

+#define TIPC_MIN_BEARER_MTU_CRYPTO     (TIPC_MIN_BEARER_MTU + EMSG_OVERHEAD)
+
 int tipc_crypto_start(struct tipc_crypto **crypto, struct net *net,
                      struct tipc_node *node);
 void tipc_crypto_stop(struct tipc_crypto **crypto);
@@ -196,5 +198,22 @@ static inline void msg_set_key_mode(struct tipc_msg *m, u32 mode)
        msg_set_bits(m, 4, 0, 0xf, mode);
 }

+/**
+ * tipc_mtu_bad_crypto - check if device MTU is too low for encrypted headers
+ * @dev: the net device that its MTU needs to be checked
+ *
+ * Return:
+ * * false - valid MTU
+ * * true  - invalid MTU
+ *
+ */
+static inline bool tipc_mtu_bad_crypto(struct net_device *dev)
+{
+       if (dev->mtu >= TIPC_MIN_BEARER_MTU_CRYPTO)
+               return false;
+       netdev_warn(dev, "MTU too low for tipc bearer\n");
+       return true;
+}
+
 #endif /* _TIPC_CRYPTO_H */
 #endif
diff --git a/net/tipc/udp_media.h b/net/tipc/udp_media.h
index e7455cc73e16..43f895bec039 100644
--- a/net/tipc/udp_media.h
+++ b/net/tipc/udp_media.h
@@ -40,6 +40,7 @@

 #include <linux/ip.h>
 #include <linux/udp.h>
+#include "crypto.h"

 int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr);
 int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b);
@@ -48,8 +49,13 @@ int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb);
 /* check if configured MTU is too low for tipc headers */
 static inline bool tipc_udp_mtu_bad(u32 mtu)
 {
-       if (mtu >= (TIPC_MIN_BEARER_MTU + sizeof(struct iphdr) +
-           sizeof(struct udphdr)))
+#ifdef CONFIG_TIPC_CRYPTO
+       int mtu_min = TIPC_MIN_BEARER_MTU_CRYPTO;
+#else
+       int mtu_min = TIPC_MIN_BEARER_MTU;
+#endif
+
+       if (mtu >= (mtu_min + sizeof(struct iphdr) + sizeof(struct udphdr)))
                return false;

        pr_warn("MTU too low for tipc bearer\n");

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net] tipc: raise the minimum bearer MTU to fit tunnel and crypto overhead
  2026-10-12 15:56 ` Tung Quang Nguyen
@ 2026-10-12 19:52   ` Joas Antonio dos Santos
  2026-10-13  9:04     ` Tung Quang Nguyen
  0 siblings, 1 reply; 4+ messages in thread
From: Joas Antonio dos Santos @ 2026-10-12 19:52 UTC (permalink / raw)
  To: Tung Quang Nguyen
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, netdev, tipc-discussion, Jon Maloy

On Mon, Oct 12, 2026, Tung Quang Nguyen wrote:
> This approach is not good because  it uses hard-coded size of TIPC crypto
> header (32).
> The size should be calculated based on tipc_ehdr.
> Could you please test below general approach ?

Hi Tung,

Agreed, deriving it from EMSG_OVERHEAD is better.  I tested your
approach on 602042bf29f6 (arm64, QEMU, KASAN), applied on its own
without my patch:

- Builds cleanly with W=1 for net/tipc/, with CONFIG_TIPC_CRYPTO=y and
  with CONFIG_TIPC_CRYPTO=n.

- Same reproducer as before (node A with 40 cluster-scope publications
  and MTU 1500, node B enabling its bearer on a veth with the MTU
  below):

    config            peer MTU   bearer on B         link   KASAN
    TIPC_CRYPTO=y        100     refused (too low)    -       none
    TIPC_CRYPTO=y        171     refused (too low)    -       none
    TIPC_CRYPTO=y        172     enabled              up      none
    TIPC_CRYPTO=y       1500     enabled              up      none
    TIPC_CRYPTO=n        100     refused (too low)    -       none
    TIPC_CRYPTO=n        139     refused (too low)    -       none
    TIPC_CRYPTO=n        140     enabled              up      none
    TIPC_CRYPTO=n       1500     enabled              up      none

  So the floor is 172 with crypto and 140 without, the same values as
  my patch, and the KASAN report from the unpatched kernel is gone.

One limitation: the reproducer lowers the MTU of B's device, so it
exercises the bearer-enable check.  The max_pkt negotiation path in
tipc_link_proto_rcv() uses the same value through
tipc_bearer_min_mtu(), but I did not forge RESET/ACTIVATE messages to
hit it separately.

Would you like me to send a v2 based on your approach (with your
Co-developed-by/Signed-off-by), or do you prefer to post it yourself
with a Reported-by/Tested-by from me?

Thanks,
Joas

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net] tipc: raise the minimum bearer MTU to fit tunnel and crypto overhead
  2026-10-12 19:52   ` Joas Antonio dos Santos
@ 2026-10-13  9:04     ` Tung Quang Nguyen
  0 siblings, 0 replies; 4+ messages in thread
From: Tung Quang Nguyen @ 2026-10-13  9:04 UTC (permalink / raw)
  To: Joas Antonio dos Santos
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, netdev@vger.kernel.org,
	tipc-discussion@lists.sourceforge.net, Jon Maloy

> Would you like me to send a v2 based on your approach (with your
> Co-developed-by/Signed-off-by), or do you prefer to post it yourself
> with a Reported-by/Tested-by from me?

Please send v2 with this tag: Suggested-by: Tung Nguyen <tung.quang.nguyen@est.tech>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-13  9:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-09 12:53 [PATCH net] tipc: raise the minimum bearer MTU to fit tunnel and crypto overhead Joas Antonio dos Santos
2026-10-12 15:56 ` Tung Quang Nguyen
2026-10-12 19:52   ` Joas Antonio dos Santos
2026-10-13  9:04     ` Tung Quang Nguyen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox