]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - net/ipv4/sysctl_net_ipv4.c
[INET]: local port range robustness
[mirror_ubuntu-hirsute-kernel.git] / net / ipv4 / sysctl_net_ipv4.c
index fabf69a9108ca6f6d42f58c3eca46b30f1ffae6b..eb286abcf5dc7f600e84c1cb43de53e90962fe50 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/sysctl.h>
 #include <linux/igmp.h>
 #include <linux/inetdevice.h>
+#include <linux/seqlock.h>
 #include <net/snmp.h>
 #include <net/icmp.h>
 #include <net/ip.h>
@@ -24,7 +25,7 @@ extern int sysctl_ip_nonlocal_bind;
 
 #ifdef CONFIG_SYSCTL
 static int zero;
-static int tcp_retr1_max = 255; 
+static int tcp_retr1_max = 255;
 static int ip_local_port_range_min[] = { 1, 1 };
 static int ip_local_port_range_max[] = { 65535, 65535 };
 #endif
@@ -37,12 +38,12 @@ static
 int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
                        void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       int val = ipv4_devconf.forwarding;
+       int val = IPV4_DEVCONF_ALL(FORWARDING);
        int ret;
 
        ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
 
-       if (write && ipv4_devconf.forwarding != val)
+       if (write && IPV4_DEVCONF_ALL(FORWARDING) != val)
                inet_forward_change();
 
        return ret;
@@ -89,6 +90,74 @@ static int ipv4_sysctl_forward_strategy(ctl_table *table,
        return 1;
 }
 
+extern seqlock_t sysctl_port_range_lock;
+extern int sysctl_local_port_range[2];
+
+/* Update system visible IP port range */
+static void set_local_port_range(int range[2])
+{
+       write_seqlock(&sysctl_port_range_lock);
+       sysctl_local_port_range[0] = range[0];
+       sysctl_local_port_range[1] = range[1];
+       write_sequnlock(&sysctl_port_range_lock);
+}
+
+/* Validate changes from /proc interface. */
+static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
+                                void __user *buffer,
+                                size_t *lenp, loff_t *ppos)
+{
+       int ret;
+       int range[2] = { sysctl_local_port_range[0],
+                        sysctl_local_port_range[1] };
+       ctl_table tmp = {
+               .data = &range,
+               .maxlen = sizeof(range),
+               .mode = table->mode,
+               .extra1 = &ip_local_port_range_min,
+               .extra2 = &ip_local_port_range_max,
+       };
+
+       ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
+
+       if (write && ret == 0) {
+               if (range[1] <= range[0])
+                       ret = -EINVAL;
+               else
+                       set_local_port_range(range);
+       }
+
+       return ret;
+}
+
+/* Validate changes from sysctl interface. */
+static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
+                                        int nlen, void __user *oldval,
+                                        size_t __user *oldlenp,
+                                       void __user *newval, size_t newlen)
+{
+       int ret;
+       int range[2] = { sysctl_local_port_range[0],
+                        sysctl_local_port_range[1] };
+       ctl_table tmp = {
+               .data = &range,
+               .maxlen = sizeof(range),
+               .mode = table->mode,
+               .extra1 = &ip_local_port_range_min,
+               .extra2 = &ip_local_port_range_max,
+       };
+
+       ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen);
+       if (ret == 0 && newval && newlen) {
+               if (range[1] <= range[0])
+                       ret = -EINVAL;
+               else
+                       set_local_port_range(range);
+       }
+       return ret;
+}
+
+
 static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file * filp,
                                       void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -187,7 +256,7 @@ static int strategy_allowed_congestion_control(ctl_table *table, int __user *nam
 }
 
 ctl_table ipv4_table[] = {
-        {
+       {
                .ctl_name       = NET_IPV4_TCP_TIMESTAMPS,
                .procname       = "tcp_timestamps",
                .data           = &sysctl_tcp_timestamps,
@@ -195,7 +264,7 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
-        {
+       {
                .ctl_name       = NET_IPV4_TCP_WINDOW_SCALING,
                .procname       = "tcp_window_scaling",
                .data           = &sysctl_tcp_window_scaling,
@@ -203,7 +272,7 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
-        {
+       {
                .ctl_name       = NET_IPV4_TCP_SACK,
                .procname       = "tcp_sack",
                .data           = &sysctl_tcp_sack,
@@ -211,7 +280,7 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
-        {
+       {
                .ctl_name       = NET_IPV4_TCP_RETRANS_COLLAPSE,
                .procname       = "tcp_retrans_collapse",
                .data           = &sysctl_tcp_retrans_collapse,
@@ -219,25 +288,25 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
-        {
+       {
                .ctl_name       = NET_IPV4_FORWARD,
                .procname       = "ip_forward",
-               .data           = &ipv4_devconf.forwarding,
+               .data           = &IPV4_DEVCONF_ALL(FORWARDING),
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &ipv4_sysctl_forward,
                .strategy       = &ipv4_sysctl_forward_strategy
        },
-        {
+       {
                .ctl_name       = NET_IPV4_DEFAULT_TTL,
                .procname       = "ip_default_ttl",
-               .data           = &sysctl_ip_default_ttl,
+               .data           = &sysctl_ip_default_ttl,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &ipv4_doint_and_flush,
                .strategy       = &ipv4_doint_and_flush_strategy,
        },
-        {
+       {
                .ctl_name       = NET_IPV4_NO_PMTU_DISC,
                .procname       = "ip_no_pmtu_disc",
                .data           = &ipv4_config.no_pmtu_disc,
@@ -427,10 +496,8 @@ ctl_table ipv4_table[] = {
                .data           = &sysctl_local_port_range,
                .maxlen         = sizeof(sysctl_local_port_range),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
-               .extra1         = ip_local_port_range_min,
-               .extra2         = ip_local_port_range_max
+               .proc_handler   = &ipv4_local_port_range,
+               .strategy       = &ipv4_sysctl_local_port_range,
        },
        {
                .ctl_name       = NET_IPV4_ICMP_ECHO_IGNORE_ALL,
@@ -646,6 +713,14 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
+       {
+               .ctl_name       = NET_TCP_FRTO_RESPONSE,
+               .procname       = "tcp_frto_response",
+               .data           = &sysctl_tcp_frto_response,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
        {
                .ctl_name       = NET_TCP_LOW_LATENCY,
                .procname       = "tcp_low_latency",
@@ -728,7 +803,7 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec,
        },
-        {
+       {
                .ctl_name       = NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS,
                .procname       = "tcp_workaround_signed_windows",
                .data           = &sysctl_tcp_workaround_signed_windows,
@@ -803,6 +878,14 @@ ctl_table ipv4_table[] = {
                .proc_handler   = &proc_allowed_congestion_control,
                .strategy       = &strategy_allowed_congestion_control,
        },
+       {
+               .ctl_name       = NET_TCP_MAX_SSTHRESH,
+               .procname       = "tcp_max_ssthresh",
+               .data           = &sysctl_tcp_max_ssthresh,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
        { .ctl_name = 0 }
 };