public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default
@ 2026-01-08 17:14 Tom Herbert
  2026-01-08 17:14 ` [PATCH net-next v2 1/4] ipv6: Check of max HBH or DestOp sysctl is zero and drop if it is Tom Herbert
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Tom Herbert @ 2026-01-08 17:14 UTC (permalink / raw)
  To: davem, kuba, netdev; +Cc: Tom Herbert

This patchset set changes the interpretation of the Destination Options
and Hop-by-Hop Options sysctl limits, net.ipv6.max_dst_opts_number and
net.ipv6.max_dst_opts_number to mean that when the sysctl is zero
processing of the associated extension header is disabled such that
packets received with the extension header are dropped.

This patch sets the default limit for Destination Options to zero
meaning that packets with Destination Options are dropped by default.
The rationale for this is that Destinations Options extension header
can be used in an effective Denial of Service attack, and Destination
Options have very little or possibly no deployment. Note that the only
non-padding Destination option supported by the kernel is the Home
Address Option (RFC6275). It is unknown if anyone is using that.

The Denial of Service attack goes like this: All an attacker needs to
do is create and MTU size packet filled  with 8 bytes Destination
Options Extension Headers. Each Destination EH simply contains a single
padding option with six bytes of zeroes. In a 1500 byte MTU size
packet, 182 of these dummy Destination Options headers can be placed
in a packet. Per RFC8200, a host must accept and process a packet with
any number of Destination Options extension headers. So when the stack
processes such a packet is a lot of work and CPU cycles that yield zero
benefit. The packet can be designed such that every byte after the IP
header requires a conditional check and branch prediction can be
rendered useless for that. This also may mean over twenty cache misses
per packet. In other words, these packets filled with dummy Destination
Options extension headers are the basis for what would be an effective
DoS attack.

Disabling Destination Options is not a major issue for the following
reasons:

* Linux kernel only supports one Destination Option (Home Address
  Option). There is no evidence this has seen any real world use

* On the Internet packets with Destination Options are dropped with
  a high enough rate such that use of Destination Options is not
  feasible

* It is unknown however quite possible that no one anywhere is using
  Destination Options for anything but experiments, class projects,
  or DoS. If someone is using them in their private network then
  it's easy enough to configure a non-zero limit for their use case

Additionally, this patch set sets the default limit of number of
Hop-by-Hop options to one. The rationale is similar to disabling
Destination options on RX however unlike Destination options
Hop-by-Hop options have one common use case in the Router
Alert option. It should be noted that RFC9673, IPv6 Hop-by-Hop
Options Processing Procedures, states "A Source MAY, based on local
configuration, allow only one Hop-by-Hop option to be included in a
packet". That implies an expectation that one Hop-by-Hop may be
suffcient.

Note that the limits on number of non-padding Destination options and
the number of Hop-by-Hop options are configurable via a sysctl.

Tom Herbert (4):
  ipv6: Check of max HBH or DestOp sysctl is zero and drop if it is
  ipv6: Disable IPv6 Destination Options RX processing by default
  ipv6: Set Hop-by-Hop options limit to 1
  ipv6: Document defaults for max_{dst|hbh}_opts_number sysctls

 Documentation/networking/ip-sysctl.rst | 38 ++++++++++++++++++--------
 include/net/ipv6.h                     |  9 ++++--
 net/ipv6/exthdrs.c                     |  6 ++--
 3 files changed, 37 insertions(+), 16 deletions(-)

-- 
2.43.0


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

* [PATCH net-next v2 1/4] ipv6: Check of max HBH or DestOp sysctl is zero and drop if it is
  2026-01-08 17:14 [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Tom Herbert
@ 2026-01-08 17:14 ` Tom Herbert
  2026-01-08 17:14 ` [PATCH net-next v2 2/4] ipv6: Disable IPv6 Destination Options RX processing by default Tom Herbert
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Tom Herbert @ 2026-01-08 17:14 UTC (permalink / raw)
  To: davem, kuba, netdev; +Cc: Tom Herbert

In IPv6 Destination options processing function check if
net->ipv6.sysctl.max_dst_opts_cnt is zero up front. If it is zero then
drop the packet since Destination Options processing is disabled.

Similarly, in IPv6 hop-by-hop options processing function check if
net->ipv6.sysctl.max_hbh_opts_cnt is zero up front. If it is zero then
drop the packet since Hop-by-Hop Options processing is disabled.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 net/ipv6/exthdrs.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index a23eb8734e15..11ff3d4df129 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -303,7 +303,8 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
 	struct net *net = dev_net(skb->dev);
 	int extlen;
 
-	if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
+	if (!net->ipv6.sysctl.max_dst_opts_cnt ||
+	    !pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
 	    !pskb_may_pull(skb, (skb_transport_offset(skb) +
 				 ((skb_transport_header(skb)[1] + 1) << 3)))) {
 		__IP6_INC_STATS(dev_net(dst_dev(dst)), idev,
@@ -1040,7 +1041,8 @@ int ipv6_parse_hopopts(struct sk_buff *skb)
 	 * sizeof(struct ipv6hdr) by definition of
 	 * hop-by-hop options.
 	 */
-	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
+	if (!net->ipv6.sysctl.max_hbh_opts_cnt ||
+	    !pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) ||
 	    !pskb_may_pull(skb, (sizeof(struct ipv6hdr) +
 				 ((skb_transport_header(skb)[1] + 1) << 3)))) {
 fail_and_free:
-- 
2.43.0


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

* [PATCH net-next v2 2/4] ipv6: Disable IPv6 Destination Options RX processing by default
  2026-01-08 17:14 [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Tom Herbert
  2026-01-08 17:14 ` [PATCH net-next v2 1/4] ipv6: Check of max HBH or DestOp sysctl is zero and drop if it is Tom Herbert
@ 2026-01-08 17:14 ` Tom Herbert
  2026-01-08 17:14 ` [PATCH net-next v2 3/4] ipv6: Set Hop-by-Hop options limit to 1 Tom Herbert
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Tom Herbert @ 2026-01-08 17:14 UTC (permalink / raw)
  To: davem, kuba, netdev; +Cc: Tom Herbert

Set IP6_DEFAULT_MAX_DST_OPTS_CNT to zero. This disables
processing of Destinations Options extension headers by default.
Processing can be enabled by setting the net.ipv6.max_dst_opts_number
to a non-zero value.

The rationale for this is that Destination Options pose a serious risk
of Denial off Service attack. The problem is that even if the
default limit is set to a small number (previously it was eight) there
is still the possibility of a DoS attack. All an attacker needs to do
is create and MTU size packet filled  with 8 bytes Destination Options
Extension Headers. Each Destination EH simply contains a single
padding option with six bytes of zeroes.

In a 1500 byte MTU size packet, 182 of these dummy Destination
Options headers can be placed in a packet. Per RFC8200, a host must
accept and process a packet with any number of Destination Options
extension headers. So when the stack processes such a packet it is
a lot of work and CPU cycles that provide zero benefit. The packet
can be designed such that every byte after the IP header requires
a conditional check and branch prediction can be rendered useless
for that. This also may mean over twenty cache misses per packet.
In other words, these packets filled with dummy Destination Options
extension headers are the basis for what would be an effective DoS
attack.

Disabling Destination Options is not a major issue for the following
reasons:

* Linux kernel only supports one Destination Option (Home Address
  Option). There is no evidence this has seen any real world use
* On the Internet packets with Destination Options are dropped with
  a high enough rate such that use of Destination Options is not
  feasible
* It is unknown however quite possible that no one anywhere is using
  Destination Options for anything but experiments, class projects,
  or DoS. If someone is using them in their private network then
  it's easy enough to configure a non-zero limit for their use case

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/net/ipv6.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 74fbf1ad8065..723a254c0b90 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -86,8 +86,11 @@ struct ip_tunnel_info;
  * silently discarded.
  */
 
-/* Default limits for Hop-by-Hop and Destination options */
-#define IP6_DEFAULT_MAX_DST_OPTS_CNT	 8
+/* Default limits for Hop-by-Hop and Destination options. By default
+ * packets received with Destination Options headers are dropped to thwart
+ * Denial of Service attacks (see sysctl documention)
+ */
+#define IP6_DEFAULT_MAX_DST_OPTS_CNT	 0
 #define IP6_DEFAULT_MAX_HBH_OPTS_CNT	 8
 #define IP6_DEFAULT_MAX_DST_OPTS_LEN	 INT_MAX /* No limit */
 #define IP6_DEFAULT_MAX_HBH_OPTS_LEN	 INT_MAX /* No limit */
-- 
2.43.0


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

* [PATCH net-next v2 3/4] ipv6: Set Hop-by-Hop options limit to 1
  2026-01-08 17:14 [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Tom Herbert
  2026-01-08 17:14 ` [PATCH net-next v2 1/4] ipv6: Check of max HBH or DestOp sysctl is zero and drop if it is Tom Herbert
  2026-01-08 17:14 ` [PATCH net-next v2 2/4] ipv6: Disable IPv6 Destination Options RX processing by default Tom Herbert
@ 2026-01-08 17:14 ` Tom Herbert
  2026-01-08 17:14 ` [PATCH net-next v2 4/4] ipv6: Document defaults for max_{dst|hbh}_opts_number sysctls Tom Herbert
  2026-01-09 19:50 ` [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Jakub Kicinski
  4 siblings, 0 replies; 7+ messages in thread
From: Tom Herbert @ 2026-01-08 17:14 UTC (permalink / raw)
  To: davem, kuba, netdev; +Cc: Tom Herbert

The Hop-by-Hop options limit was a default of 8 meaning that up to
eight Hop-by-Hop options would be received in packet before the limit
is exceeded and the packet is dropped. This limit is too high and
makes the node susceptible to DoS attack. Note it's not just the
options themselves, but a lot of padding can be used between options
(.e.g. up to seven PAD1 options). It's pretty easy for an attacker to
fabricate a packet with nothing but eight unknown option types and
padding between the options to force over a hundred conditionals to
be evaluated and at least eight cache misses per packet resulting
in no productive work being done.

The new limit is one. This is based on the fact that there are some
hop-by-hop option in deployment like router alert option, however they
tend to be singleton options and it's unlikely there is significant use
of more than one option in a packet. From a protocol perspective,
RFC9673 states:

"A Source MAY, based on local configuration, allow only one Hop-by-Hop
option to be included in a packet"

We can infer that implies that at most one Hop-by-Hop option is
sufficient.

It should be noted that Hop-by-Hops are unusable in the general
Internet hand packets with Hop-by-Hop Options are commonly dropped
by routers. The only realistic use case for Hop-by-Hop options is
limited dominas, and if a limited domain needs more than one HBH option
in a packet it's easy enough to configure the sysctl to whatever limit
they want.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/net/ipv6.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 723a254c0b90..62ed44894e96 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -91,7 +91,7 @@ struct ip_tunnel_info;
  * Denial of Service attacks (see sysctl documention)
  */
 #define IP6_DEFAULT_MAX_DST_OPTS_CNT	 0
-#define IP6_DEFAULT_MAX_HBH_OPTS_CNT	 8
+#define IP6_DEFAULT_MAX_HBH_OPTS_CNT	 1
 #define IP6_DEFAULT_MAX_DST_OPTS_LEN	 INT_MAX /* No limit */
 #define IP6_DEFAULT_MAX_HBH_OPTS_LEN	 INT_MAX /* No limit */
 
-- 
2.43.0


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

* [PATCH net-next v2 4/4] ipv6: Document defaults for max_{dst|hbh}_opts_number sysctls
  2026-01-08 17:14 [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Tom Herbert
                   ` (2 preceding siblings ...)
  2026-01-08 17:14 ` [PATCH net-next v2 3/4] ipv6: Set Hop-by-Hop options limit to 1 Tom Herbert
@ 2026-01-08 17:14 ` Tom Herbert
  2026-01-09 19:50 ` [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Jakub Kicinski
  4 siblings, 0 replies; 7+ messages in thread
From: Tom Herbert @ 2026-01-08 17:14 UTC (permalink / raw)
  To: davem, kuba, netdev; +Cc: Tom Herbert

In the descriptions of max_dst_opts_number and max_hbh_opts_number
sysctls add text about how a zero setting means that a packet with
any Destination or Hop-by-Hop options is dropped.

Report the default for max_dst_opts_number to be zero (i.e. packets
with Destination options are dropped by default), and add a
justification.

Report the default for max_hbh_opts_number to be one.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 Documentation/networking/ip-sysctl.rst | 38 ++++++++++++++++++--------
 1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index bc9a01606daf..de078f7f6a17 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -2474,20 +2474,36 @@ mld_qrv - INTEGER
 	Minimum: 1 (as specified by RFC6636 4.5)
 
 max_dst_opts_number - INTEGER
-	Maximum number of non-padding TLVs allowed in a Destination
-	options extension header. If this value is less than zero
-	then unknown options are disallowed and the number of known
-	TLVs allowed is the absolute value of this number.
-
-	Default: 8
+        Maximum number of non-padding TLVs allowed in a Destination
+        options extension header. If this value is zero then receive
+        Destination Options processing is disabled in which case packets
+        with the Destination Options extension header are dropped. If
+        this value is less than zero then unknown options are disallowed
+        and the number of known TLVs allowed is the absolute value of
+        this number.
+
+        The default is zero which means the all received packets with
+        Destination Options extension header are dropped. The rationale is that
+        for the vast majority of hosts, Destination Options serve no purpose.
+        In the thirty years of IPv6 no broadly useful IPv6 Destination options
+        have been defined, they have no security or even checksum protection,
+        latest data shows the Destination have drop rates on the Internet
+        from ten percent to more than thirty percent (depending on the size of
+        the extension header). They also have the potential to be used as a
+        Denial of Service attack.
+
+        Default: 0
 
 max_hbh_opts_number - INTEGER
 	Maximum number of non-padding TLVs allowed in a Hop-by-Hop
-	options extension header. If this value is less than zero
-	then unknown options are disallowed and the number of known
-	TLVs allowed is the absolute value of this number.
-
-	Default: 8
+	options extension header. If this value is zero then receive
+        Hop-by-Hop Options processing is disabled in which case packets
+        with the Hop-by-Hop Options extension header are dropped.
+        If this value is less than zero then unknown options are disallowed
+        and the number of known TLVs allowed is the absolute value of this
+        number.
+
+        Default: 1
 
 max_dst_opts_length - INTEGER
 	Maximum length allowed for a Destination options extension
-- 
2.43.0


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

* Re: [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default
  2026-01-08 17:14 [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Tom Herbert
                   ` (3 preceding siblings ...)
  2026-01-08 17:14 ` [PATCH net-next v2 4/4] ipv6: Document defaults for max_{dst|hbh}_opts_number sysctls Tom Herbert
@ 2026-01-09 19:50 ` Jakub Kicinski
  2026-01-13 19:54   ` Tom Herbert
  4 siblings, 1 reply; 7+ messages in thread
From: Jakub Kicinski @ 2026-01-09 19:50 UTC (permalink / raw)
  To: Tom Herbert; +Cc: davem, netdev

On Thu,  8 Jan 2026 09:14:52 -0800 Tom Herbert wrote:
> This patchset set changes the interpretation of the Destination Options
> and Hop-by-Hop Options sysctl limits, net.ipv6.max_dst_opts_number and
> net.ipv6.max_dst_opts_number to mean that when the sysctl is zero
> processing of the associated extension header is disabled such that
> packets received with the extension header are dropped.

Hi Tom!

Unfortunately, this breaks GRE:
https://netdev.bots.linux.dev/contest.html?pw-n=0&branch=net-next-2026-01-09--18-00&pw-n=0&pass=0

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

* Re: [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default
  2026-01-09 19:50 ` [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Jakub Kicinski
@ 2026-01-13 19:54   ` Tom Herbert
  0 siblings, 0 replies; 7+ messages in thread
From: Tom Herbert @ 2026-01-13 19:54 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev

On Fri, Jan 9, 2026 at 11:50 AM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Thu,  8 Jan 2026 09:14:52 -0800 Tom Herbert wrote:
> > This patchset set changes the interpretation of the Destination Options
> > and Hop-by-Hop Options sysctl limits, net.ipv6.max_dst_opts_number and
> > net.ipv6.max_dst_opts_number to mean that when the sysctl is zero
> > processing of the associated extension header is disabled such that
> > packets received with the extension header are dropped.
>
> Hi Tom!
>
> Unfortunately, this breaks GRE:
> https://netdev.bots.linux.dev/contest.html?pw-n=0&branch=net-next-2026-01-09--18-00&pw-n=0&pass=0

Jakub,

There's a hidden Destination Option used by GREv6 in
IPV6_TLV_TNL_ENCAP_LIMIT (not defined with the other TLVs and not
processed in the main TLV loop). So probably can't disable Destination
options by default. I'll respin the patch set to restrict EH as much
as possible to avoid DoS.

Tom

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

end of thread, other threads:[~2026-01-13 19:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-08 17:14 [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Tom Herbert
2026-01-08 17:14 ` [PATCH net-next v2 1/4] ipv6: Check of max HBH or DestOp sysctl is zero and drop if it is Tom Herbert
2026-01-08 17:14 ` [PATCH net-next v2 2/4] ipv6: Disable IPv6 Destination Options RX processing by default Tom Herbert
2026-01-08 17:14 ` [PATCH net-next v2 3/4] ipv6: Set Hop-by-Hop options limit to 1 Tom Herbert
2026-01-08 17:14 ` [PATCH net-next v2 4/4] ipv6: Document defaults for max_{dst|hbh}_opts_number sysctls Tom Herbert
2026-01-09 19:50 ` [PATCH net-next v2 0/4] ipv6: Disable IPv6 Destination Options RX processing by default Jakub Kicinski
2026-01-13 19:54   ` Tom Herbert

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