From 61690148345a4a1ccced61ad9c44862f74d947cf Mon Sep 17 00:00:00 2001 From: Robin Holt Date: Wed, 20 Oct 2010 02:03:37 +0000 Subject: [PATCH] Limit sysctl_tcp_mem and sysctl_udp_mem initializers to prevent integer overflows. [ Upstream fixed this in a different way as parts of the commits: 8d987e5c7510 (net: avoid limits overflow) a9febbb4bd13 (sysctl: min/max bounds are optional) 27b3d80a7b6a (sysctl: fix min/max handling in __do_proc_doulongvec_minmax()) -DaveM ] On a 16TB x86_64 machine, sysctl_tcp_mem[2], sysctl_udp_mem[2], and sysctl_sctp_mem[2] can integer overflow. Set limit such that they are maximized without overflowing. Signed-off-by: Robin Holt To: "David S. Miller" Cc: Willy Tarreau Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-sctp@vger.kernel.org Cc: Alexey Kuznetsov Cc: "Pekka Savola (ipv6)" Cc: James Morris Cc: Hideaki YOSHIFUJI Cc: Patrick McHardy Cc: Vlad Yasevich Cc: Sridhar Samudrala Signed-off-by: Greg Kroah-Hartman --- net/ipv4/tcp.c | 4 +++- net/ipv4/udp.c | 4 +++- net/sctp/protocol.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 46783087137d..734fe94827dc 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2940,12 +2940,14 @@ void __init tcp_init(void) /* Set the pressure threshold to be a fraction of global memory that * is up to 1/2 at 256 MB, decreasing toward zero with the amount of - * memory, with a floor of 128 pages. + * memory, with a floor of 128 pages, and a ceiling that prevents an + * integer overflow. */ nr_pages = totalram_pages - totalhigh_pages; limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); limit = max(limit, 128UL); + limit = min(limit, INT_MAX * 4UL / 3 / 2); sysctl_tcp_mem[0] = limit / 4 * 3; sysctl_tcp_mem[1] = limit; sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index c322f4429fc9..31db78ca7469 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1832,12 +1832,14 @@ void __init udp_init(void) udp_table_init(&udp_table); /* Set the pressure threshold up by the same strategy of TCP. It is a * fraction of global memory that is up to 1/2 at 256 MB, decreasing - * toward zero with the amount of memory, with a floor of 128 pages. + * toward zero with the amount of memory, with a floor of 128 pages, + * and a ceiling that prevents an integer overflow. */ nr_pages = totalram_pages - totalhigh_pages; limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); limit = max(limit, 128UL); + limit = min(limit, INT_MAX * 4UL / 3 / 2); sysctl_udp_mem[0] = limit / 4 * 3; sysctl_udp_mem[1] = limit; sysctl_udp_mem[2] = sysctl_udp_mem[0] * 2; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 612dc878e05c..619f96568e8e 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1157,7 +1157,8 @@ SCTP_STATIC __init int sctp_init(void) /* Set the pressure threshold to be a fraction of global memory that * is up to 1/2 at 256 MB, decreasing toward zero with the amount of - * memory, with a floor of 128 pages. + * memory, with a floor of 128 pages, and a ceiling that prevents an + * integer overflow. * Note this initalizes the data in sctpv6_prot too * Unabashedly stolen from tcp_init */ @@ -1165,6 +1166,7 @@ SCTP_STATIC __init int sctp_init(void) limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); limit = max(limit, 128UL); + limit = min(limit, INT_MAX * 4UL / 3 / 2); sysctl_sctp_mem[0] = limit / 4 * 3; sysctl_sctp_mem[1] = limit; sysctl_sctp_mem[2] = sysctl_sctp_mem[0] * 2; -- 2.39.5