1 From 92988de9edaa8e54456640dbcd866e74c558c911 Mon Sep 17 00:00:00 2001
2 From: Robin Holt <holt@sgi.com>
3 Date: Wed, 20 Oct 2010 02:03:37 +0000
4 Subject: Limit sysctl_tcp_mem and sysctl_udp_mem initializers to prevent integer overflows.
6 From: Robin Holt <holt@sgi.com>
8 [ Problem was fixed differently upstream. -DaveM ]
10 On a 16TB x86_64 machine, sysctl_tcp_mem[2], sysctl_udp_mem[2], and
11 sysctl_sctp_mem[2] can integer overflow. Set limit such that they are
12 maximized without overflowing.
14 Signed-off-by: Robin Holt <holt@sgi.com>
15 To: "David S. Miller" <davem@davemloft.net>
16 Cc: Willy Tarreau <w@1wt.eu>
17 Cc: linux-kernel@vger.kernel.org
18 Cc: netdev@vger.kernel.org
19 Cc: linux-sctp@vger.kernel.org
20 Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
21 Cc: "Pekka Savola (ipv6)" <pekkas@netcore.fi>
22 Cc: James Morris <jmorris@namei.org>
23 Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
24 Cc: Patrick McHardy <kaber@trash.net>
25 Cc: Vlad Yasevich <vladislav.yasevich@hp.com>
26 Cc: Sridhar Samudrala <sri@us.ibm.com>
27 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
29 net/ipv4/tcp.c | 4 +++-
30 net/ipv4/udp.c | 4 +++-
31 net/sctp/protocol.c | 4 +++-
32 3 files changed, 9 insertions(+), 3 deletions(-)
36 @@ -2754,12 +2754,14 @@ void __init tcp_init(void)
38 /* Set the pressure threshold to be a fraction of global memory that
39 * is up to 1/2 at 256 MB, decreasing toward zero with the amount of
40 - * memory, with a floor of 128 pages.
41 + * memory, with a floor of 128 pages, and a ceiling that prevents an
44 nr_pages = totalram_pages - totalhigh_pages;
45 limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
46 limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
47 limit = max(limit, 128UL);
48 + limit = min(limit, INT_MAX * 4UL / 3 / 2);
49 sysctl_tcp_mem[0] = limit / 4 * 3;
50 sysctl_tcp_mem[1] = limit;
51 sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2;
54 @@ -1722,11 +1722,13 @@ void __init udp_init(void)
56 /* Set the pressure threshold up by the same strategy of TCP. It is a
57 * fraction of global memory that is up to 1/2 at 256 MB, decreasing
58 - * toward zero with the amount of memory, with a floor of 128 pages.
59 + * toward zero with the amount of memory, with a floor of 128 pages,
60 + * and a ceiling that prevents an integer overflow.
62 limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
63 limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
64 limit = max(limit, 128UL);
65 + limit = min(limit, INT_MAX * 4UL / 3 / 2);
66 sysctl_udp_mem[0] = limit / 4 * 3;
67 sysctl_udp_mem[1] = limit;
68 sysctl_udp_mem[2] = sysctl_udp_mem[0] * 2;
69 --- a/net/sctp/protocol.c
70 +++ b/net/sctp/protocol.c
71 @@ -1179,7 +1179,8 @@ SCTP_STATIC __init int sctp_init(void)
73 /* Set the pressure threshold to be a fraction of global memory that
74 * is up to 1/2 at 256 MB, decreasing toward zero with the amount of
75 - * memory, with a floor of 128 pages.
76 + * memory, with a floor of 128 pages, and a ceiling that prevents an
78 * Note this initalizes the data in sctpv6_prot too
79 * Unabashedly stolen from tcp_init
81 @@ -1187,6 +1188,7 @@ SCTP_STATIC __init int sctp_init(void)
82 limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
83 limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
84 limit = max(limit, 128UL);
85 + limit = min(limit, INT_MAX * 4UL / 3 / 2);
86 sysctl_sctp_mem[0] = limit / 4 * 3;
87 sysctl_sctp_mem[1] = limit;
88 sysctl_sctp_mem[2] = sysctl_sctp_mem[0] * 2;