|
@@ -26,6 +26,7 @@
|
|
#include <linux/mm.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/audit.h>
|
|
#include <linux/audit.h>
|
|
|
|
+#include <linux/user_namespace.h>
|
|
#include <net/net_namespace.h>
|
|
#include <net/net_namespace.h>
|
|
|
|
|
|
#include <linux/netfilter/x_tables.h>
|
|
#include <linux/netfilter/x_tables.h>
|
|
@@ -1226,6 +1227,8 @@ int xt_proto_init(struct net *net, u_int8_t af)
|
|
#ifdef CONFIG_PROC_FS
|
|
#ifdef CONFIG_PROC_FS
|
|
char buf[XT_FUNCTION_MAXNAMELEN];
|
|
char buf[XT_FUNCTION_MAXNAMELEN];
|
|
struct proc_dir_entry *proc;
|
|
struct proc_dir_entry *proc;
|
|
|
|
+ kuid_t root_uid;
|
|
|
|
+ kgid_t root_gid;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
if (af >= ARRAY_SIZE(xt_prefix))
|
|
if (af >= ARRAY_SIZE(xt_prefix))
|
|
@@ -1233,12 +1236,17 @@ int xt_proto_init(struct net *net, u_int8_t af)
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_PROC_FS
|
|
#ifdef CONFIG_PROC_FS
|
|
|
|
+ root_uid = make_kuid(net->user_ns, 0);
|
|
|
|
+ root_gid = make_kgid(net->user_ns, 0);
|
|
|
|
+
|
|
strlcpy(buf, xt_prefix[af], sizeof(buf));
|
|
strlcpy(buf, xt_prefix[af], sizeof(buf));
|
|
strlcat(buf, FORMAT_TABLES, sizeof(buf));
|
|
strlcat(buf, FORMAT_TABLES, sizeof(buf));
|
|
proc = proc_create_data(buf, 0440, net->proc_net, &xt_table_ops,
|
|
proc = proc_create_data(buf, 0440, net->proc_net, &xt_table_ops,
|
|
(void *)(unsigned long)af);
|
|
(void *)(unsigned long)af);
|
|
if (!proc)
|
|
if (!proc)
|
|
goto out;
|
|
goto out;
|
|
|
|
+ if (uid_valid(root_uid) && gid_valid(root_gid))
|
|
|
|
+ proc_set_user(proc, root_uid, root_gid);
|
|
|
|
|
|
strlcpy(buf, xt_prefix[af], sizeof(buf));
|
|
strlcpy(buf, xt_prefix[af], sizeof(buf));
|
|
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
|
|
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
|
|
@@ -1246,6 +1254,8 @@ int xt_proto_init(struct net *net, u_int8_t af)
|
|
(void *)(unsigned long)af);
|
|
(void *)(unsigned long)af);
|
|
if (!proc)
|
|
if (!proc)
|
|
goto out_remove_tables;
|
|
goto out_remove_tables;
|
|
|
|
+ if (uid_valid(root_uid) && gid_valid(root_gid))
|
|
|
|
+ proc_set_user(proc, root_uid, root_gid);
|
|
|
|
|
|
strlcpy(buf, xt_prefix[af], sizeof(buf));
|
|
strlcpy(buf, xt_prefix[af], sizeof(buf));
|
|
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
|
|
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
|
|
@@ -1253,6 +1263,8 @@ int xt_proto_init(struct net *net, u_int8_t af)
|
|
(void *)(unsigned long)af);
|
|
(void *)(unsigned long)af);
|
|
if (!proc)
|
|
if (!proc)
|
|
goto out_remove_matches;
|
|
goto out_remove_matches;
|
|
|
|
+ if (uid_valid(root_uid) && gid_valid(root_gid))
|
|
|
|
+ proc_set_user(proc, root_uid, root_gid);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
return 0;
|
|
return 0;
|