From 231092a6df3979397498f04716d93d1c20369e78 Mon Sep 17 00:00:00 2001 From: Thomas Tanaka Date: Thu, 1 Oct 2015 17:17:52 -0700 Subject: [PATCH] export host-only net/core and net/ipv4 parameters to a container as read-only export host-only net/core and net/ipv4 parameters to a container as read-only For Oracle applications to run inside the Linux container, certain net/core, net/ipv4 sysctl parameters need to be available. On UEK2 and later kernels upto v3.5, these parameters were exported as *read-only* to a container. However, in the newer kernels, upstream has abandoned exporting it even in read-only mode. To be able to support these applications unmodified on UEK4, we need to restore that functionality. This patch does just that. There is a plan to explore this further to come up with list of *must have* parameters to be available inside containers and then propose upstream to move them in the network namespace sysctls. Orabug: 21880402 This patch is a backport from UEK3 (Orabug 21151210) Acked-by: Guru Anbalagane Signed-off-by: Thomas Tanaka --- net/core/sysctl_net_core.c | 14 +++++++++++++- net/ipv4/sysctl_net_ipv4.c | 12 +++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 95b6139d710c..3fec1adf2ec0 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -415,10 +415,22 @@ static __net_init int sysctl_core_net_init(struct net *net) tbl = netns_core_table; if (!net_eq(net, &init_net)) { - tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); + int cur; + struct ctl_table *tmp; + + tbl = kmalloc(sizeof(netns_core_table) + sizeof(net_core_table) - 1, + GFP_KERNEL); if (tbl == NULL) goto err_dup; + memcpy(tbl, netns_core_table, sizeof(netns_core_table)); + cur = ARRAY_SIZE(netns_core_table) - 1; + memcpy(tbl + cur, net_core_table, sizeof(net_core_table)); + for (tmp = net_core_table; tmp->procname; tmp++) { + tbl[cur].mode = 0444; /* set read-only */ + cur++; + } + tbl[0].data = &net->core.sysctl_somaxconn; /* Don't export any sysctls to unprivileged users */ diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index c3852a7ff3c7..3d2475749728 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -907,11 +907,21 @@ static __net_init int ipv4_sysctl_init_net(struct net *net) table = ipv4_net_table; if (!net_eq(net, &init_net)) { int i; + struct ctl_table *tmp; - table = kmemdup(table, sizeof(ipv4_net_table), GFP_KERNEL); + table = kmalloc(sizeof(ipv4_net_table) + sizeof(ipv4_table) - 1, + GFP_KERNEL); if (!table) goto err_alloc; + memcpy(table, ipv4_net_table, sizeof(ipv4_net_table)); + i = ARRAY_SIZE(ipv4_net_table) - 1; + memcpy(table + i, ipv4_table, sizeof(ipv4_table)); + for (tmp = ipv4_table; tmp->procname; tmp++) { + table[i].mode = 0444; /* set read-only */ + i++; + } + /* Update the variables to point into the current struct net */ for (i = 0; i < ARRAY_SIZE(ipv4_net_table) - 1; i++) table[i].data += (void *)net - (void *)&init_net; -- 2.50.1