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 <guru.anbalagane@oracle.com>
Signed-off-by: Thomas Tanaka <thomas.tanaka@oracle.com>
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 */
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;