| From: "bingtian.ly@taobao.com" <bingtian.ly@taobao.com> |
| Date: Wed, 23 Jan 2013 20:35:28 +0000 |
| Subject: net: avoid to hang up on sending due to sysctl configuration |
| overflow. |
| |
| commit cdda88912d62f9603d27433338a18be83ef23ac1 upstream. |
| |
| I found if we write a larger than 4GB value to some sysctl |
| variables, the sending syscall will hang up forever, because these |
| variables are 32 bits, such large values make them overflow to 0 or |
| negative. |
| |
| This patch try to fix overflow or prevent from zero value setup |
| of below sysctl variables: |
| |
| net.core.wmem_default |
| net.core.rmem_default |
| |
| net.core.rmem_max |
| net.core.wmem_max |
| |
| net.ipv4.udp_rmem_min |
| net.ipv4.udp_wmem_min |
| |
| net.ipv4.tcp_wmem |
| net.ipv4.tcp_rmem |
| |
| Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> |
| Signed-off-by: Li Yu <raise.sail@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| [bwh: Backported to 3.2: |
| - Adjust context |
| - Delete now-unused 'zero' variable] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| net/core/sysctl_net_core.c | 14 ++++++++++---- |
| net/ipv4/sysctl_net_ipv4.c | 11 +++++++---- |
| 2 files changed, 17 insertions(+), 8 deletions(-) |
| |
| --- a/net/core/sysctl_net_core.c |
| +++ b/net/core/sysctl_net_core.c |
| @@ -22,6 +22,8 @@ |
| static int zero = 0; |
| static int ushort_max = USHRT_MAX; |
| |
| +static int one = 1; |
| + |
| #ifdef CONFIG_RPS |
| static int rps_sock_flow_sysctl(ctl_table *table, int write, |
| void __user *buffer, size_t *lenp, loff_t *ppos) |
| @@ -89,28 +91,32 @@ static struct ctl_table net_core_table[] |
| .data = &sysctl_wmem_max, |
| .maxlen = sizeof(int), |
| .mode = 0644, |
| - .proc_handler = proc_dointvec |
| + .proc_handler = proc_dointvec_minmax, |
| + .extra1 = &one, |
| }, |
| { |
| .procname = "rmem_max", |
| .data = &sysctl_rmem_max, |
| .maxlen = sizeof(int), |
| .mode = 0644, |
| - .proc_handler = proc_dointvec |
| + .proc_handler = proc_dointvec_minmax, |
| + .extra1 = &one, |
| }, |
| { |
| .procname = "wmem_default", |
| .data = &sysctl_wmem_default, |
| .maxlen = sizeof(int), |
| .mode = 0644, |
| - .proc_handler = proc_dointvec |
| + .proc_handler = proc_dointvec_minmax, |
| + .extra1 = &one, |
| }, |
| { |
| .procname = "rmem_default", |
| .data = &sysctl_rmem_default, |
| .maxlen = sizeof(int), |
| .mode = 0644, |
| - .proc_handler = proc_dointvec |
| + .proc_handler = proc_dointvec_minmax, |
| + .extra1 = &one, |
| }, |
| { |
| .procname = "dev_weight", |
| --- a/net/ipv4/sysctl_net_ipv4.c |
| +++ b/net/ipv4/sysctl_net_ipv4.c |
| @@ -24,7 +24,7 @@ |
| #include <net/inet_frag.h> |
| #include <net/ping.h> |
| |
| -static int zero; |
| +static int one = 1; |
| static int tcp_retr1_max = 255; |
| static int ip_local_port_range_min[] = { 1, 1 }; |
| static int ip_local_port_range_max[] = { 65535, 65535 }; |
| @@ -448,14 +448,16 @@ static struct ctl_table ipv4_table[] = { |
| .data = &sysctl_tcp_wmem, |
| .maxlen = sizeof(sysctl_tcp_wmem), |
| .mode = 0644, |
| - .proc_handler = proc_dointvec |
| + .proc_handler = proc_dointvec_minmax, |
| + .extra1 = &one, |
| }, |
| { |
| .procname = "tcp_rmem", |
| .data = &sysctl_tcp_rmem, |
| .maxlen = sizeof(sysctl_tcp_rmem), |
| .mode = 0644, |
| - .proc_handler = proc_dointvec |
| + .proc_handler = proc_dointvec_minmax, |
| + .extra1 = &one, |
| }, |
| { |
| .procname = "tcp_app_win", |
| @@ -662,7 +664,7 @@ static struct ctl_table ipv4_table[] = { |
| .maxlen = sizeof(sysctl_udp_rmem_min), |
| .mode = 0644, |
| .proc_handler = proc_dointvec_minmax, |
| - .extra1 = &zero |
| + .extra1 = &one |
| }, |
| { |
| .procname = "udp_wmem_min", |
| @@ -670,7 +672,7 @@ static struct ctl_table ipv4_table[] = { |
| .maxlen = sizeof(sysctl_udp_wmem_min), |
| .mode = 0644, |
| .proc_handler = proc_dointvec_minmax, |
| - .extra1 = &zero |
| + .extra1 = &one |
| }, |
| { } |
| }; |