[PATCH net-next] icmp: Add icmp_timestamp_ignore_all to control ICMP_TIMESTAMP

From: ye.xingchen
Date: Fri May 17 2024 - 05:27:27 EST


From: YeXingchen <ye.xingchen@xxxxxxxxxx>

The CVE-1999-0524 became a medium risk vulnerability in May of this year.

In some embedded systems, firewalls such as iptables maybe cannot to use.
For embedded systems where firewalls can't be used and devices that don't
require icmp timestamp, provide the icmp_timestamp_ignore_all interface,
which ignores all icmp timestamp messages to circumvent the vulnerability.

Signed-off-by: YeXingchen <ye.xingchen@xxxxxxxxxx>
---
Documentation/networking/ip-sysctl.rst | 6 ++++++
.../networking/net_cachelines/netns_ipv4_sysctl.rst | 1 +
include/net/netns/ipv4.h | 1 +
include/uapi/linux/sysctl.h | 1 +
net/ipv4/icmp.c | 8 ++++++++
net/ipv4/sysctl_net_ipv4.c | 9 +++++++++
6 files changed, 26 insertions(+)

diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index bd50df6a5a42..41eb3de61659 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -1441,6 +1441,12 @@ icmp_ratelimit - INTEGER

Default: 1000

+icmp_timestamp_ignore_all - BOOLEAN
+ If set non-zero, then the kernel will ignore all ICMP TIMESTAMP
+ requests sent to it.
+
+ Default: 0
+
icmp_msgs_per_sec - INTEGER
Limit maximal number of ICMP packets sent per second from this host.
Only messages whose type matches icmp_ratemask (see below) are
diff --git a/Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst b/Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst
index 9b87089a84c6..ed72f67c8f72 100644
--- a/Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst
+++ b/Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst
@@ -38,6 +38,7 @@ u8 sysctl_icmp_ignore_bogus_error_responses
u8 sysctl_icmp_errors_use_inbound_ifaddr
int sysctl_icmp_ratelimit
int sysctl_icmp_ratemask
+u8 sysctl_icmp_timestamp_ignore_all
u32 ip_rt_min_pmtu - -
int ip_rt_mtu_expires - -
int ip_rt_min_advmss - -
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index c356c458b340..7364c469e7eb 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -113,6 +113,7 @@ struct netns_ipv4 {
u8 sysctl_icmp_echo_ignore_broadcasts;
u8 sysctl_icmp_ignore_bogus_error_responses;
u8 sysctl_icmp_errors_use_inbound_ifaddr;
+ u8 sysctl_icmp_timestamp_ignore_all;
int sysctl_icmp_ratelimit;
int sysctl_icmp_ratemask;

diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h
index 8981f00204db..ef8640947f4e 100644
--- a/include/uapi/linux/sysctl.h
+++ b/include/uapi/linux/sysctl.h
@@ -426,6 +426,7 @@ enum
NET_TCP_ALLOWED_CONG_CONTROL=123,
NET_TCP_MAX_SSTHRESH=124,
NET_TCP_FRTO_RESPONSE=125,
+ NET_IPV4_ICMP_TIMESTAMP_IGNORE_ALL = 126,
};

enum {
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index ab6d0d98dbc3..6fa5c26cf402 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -1152,6 +1152,11 @@ EXPORT_SYMBOL_GPL(icmp_build_probe);
static enum skb_drop_reason icmp_timestamp(struct sk_buff *skb)
{
struct icmp_bxm icmp_param;
+ struct net *net;
+
+ if (READ_ONCE(net->ipv4.sysctl_icmp_timestamp_ignore_all))
+ return SKB_NOT_DROPPED_YET;
+
/*
* Too short.
*/
@@ -1469,6 +1474,9 @@ static int __net_init icmp_sk_init(struct net *net)
net->ipv4.sysctl_icmp_echo_enable_probe = 0;
net->ipv4.sysctl_icmp_echo_ignore_broadcasts = 1;

+ /* Control parameters for TIMESTAMP replies. */
+ net->ipv4.sysctl_icmp_timestamp_ignore_all = 0;
+
/* Control parameter - ignore bogus broadcast responses? */
net->ipv4.sysctl_icmp_ignore_bogus_error_responses = 1;

diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 162a0a3b6ba5..b002426c3d9c 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -651,6 +651,15 @@ static struct ctl_table ipv4_net_table[] = {
.mode = 0644,
.proc_handler = ipv4_ping_group_range,
},
+ {
+ .procname = "icmp_timestamp_ignore_all",
+ .data = &init_net.ipv4.sysctl_icmp_timestamp_ignore_all,
+ .maxlen = sizeof(u8),
+ .mode = 0644,
+ .proc_handler = proc_dou8vec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE
+ },
#ifdef CONFIG_NET_L3_MASTER_DEV
{
.procname = "raw_l3mdev_accept",
--
2.25.1