Loading include/linux/user_namespace.h +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ enum ucount_type { UCOUNT_PID_NAMESPACES, UCOUNT_UTS_NAMESPACES, UCOUNT_IPC_NAMESPACES, UCOUNT_NET_NAMESPACES, UCOUNT_CGROUP_NAMESPACES, UCOUNT_COUNTS, }; Loading include/net/net_namespace.h +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ struct net { struct list_head exit_list; /* Use only net_mutex */ struct user_namespace *user_ns; /* Owning user namespace */ struct ucounts *ucounts; spinlock_t nsid_lock; struct idr netns_ids; Loading kernel/ucount.c +1 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ static struct ctl_table user_table[] = { UCOUNT_ENTRY("max_pid_namespaces"), UCOUNT_ENTRY("max_uts_namespaces"), UCOUNT_ENTRY("max_ipc_namespaces"), UCOUNT_ENTRY("max_net_namespaces"), UCOUNT_ENTRY("max_cgroup_namespaces"), { } }; Loading net/core/net_namespace.c +21 −1 Original line number Diff line number Diff line Loading @@ -266,6 +266,16 @@ struct net *get_net_ns_by_id(struct net *net, int id) return peer; } static struct ucounts *inc_net_namespaces(struct user_namespace *ns) { return inc_ucount(ns, current_euid(), UCOUNT_NET_NAMESPACES); } static void dec_net_namespaces(struct ucounts *ucounts) { dec_ucount(ucounts, UCOUNT_NET_NAMESPACES); } /* * setup_net runs the initializers for the network namespace object. */ Loading Loading @@ -351,19 +361,27 @@ void net_drop_ns(void *p) struct net *copy_net_ns(unsigned long flags, struct user_namespace *user_ns, struct net *old_net) { struct ucounts *ucounts; struct net *net; int rv; if (!(flags & CLONE_NEWNET)) return get_net(old_net); ucounts = inc_net_namespaces(user_ns); if (!ucounts) return ERR_PTR(-ENFILE); net = net_alloc(); if (!net) if (!net) { dec_net_namespaces(ucounts); return ERR_PTR(-ENOMEM); } get_user_ns(user_ns); mutex_lock(&net_mutex); net->ucounts = ucounts; rv = setup_net(net, user_ns); if (rv == 0) { rtnl_lock(); Loading @@ -372,6 +390,7 @@ struct net *copy_net_ns(unsigned long flags, } mutex_unlock(&net_mutex); if (rv < 0) { dec_net_namespaces(ucounts); put_user_ns(user_ns); net_drop_ns(net); return ERR_PTR(rv); Loading Loading @@ -444,6 +463,7 @@ static void cleanup_net(struct work_struct *work) /* Finally it is safe to free my network namespace structure */ list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { list_del_init(&net->exit_list); dec_net_namespaces(net->ucounts); put_user_ns(net->user_ns); net_drop_ns(net); } Loading Loading
include/linux/user_namespace.h +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ enum ucount_type { UCOUNT_PID_NAMESPACES, UCOUNT_UTS_NAMESPACES, UCOUNT_IPC_NAMESPACES, UCOUNT_NET_NAMESPACES, UCOUNT_CGROUP_NAMESPACES, UCOUNT_COUNTS, }; Loading
include/net/net_namespace.h +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ struct net { struct list_head exit_list; /* Use only net_mutex */ struct user_namespace *user_ns; /* Owning user namespace */ struct ucounts *ucounts; spinlock_t nsid_lock; struct idr netns_ids; Loading
kernel/ucount.c +1 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ static struct ctl_table user_table[] = { UCOUNT_ENTRY("max_pid_namespaces"), UCOUNT_ENTRY("max_uts_namespaces"), UCOUNT_ENTRY("max_ipc_namespaces"), UCOUNT_ENTRY("max_net_namespaces"), UCOUNT_ENTRY("max_cgroup_namespaces"), { } }; Loading
net/core/net_namespace.c +21 −1 Original line number Diff line number Diff line Loading @@ -266,6 +266,16 @@ struct net *get_net_ns_by_id(struct net *net, int id) return peer; } static struct ucounts *inc_net_namespaces(struct user_namespace *ns) { return inc_ucount(ns, current_euid(), UCOUNT_NET_NAMESPACES); } static void dec_net_namespaces(struct ucounts *ucounts) { dec_ucount(ucounts, UCOUNT_NET_NAMESPACES); } /* * setup_net runs the initializers for the network namespace object. */ Loading Loading @@ -351,19 +361,27 @@ void net_drop_ns(void *p) struct net *copy_net_ns(unsigned long flags, struct user_namespace *user_ns, struct net *old_net) { struct ucounts *ucounts; struct net *net; int rv; if (!(flags & CLONE_NEWNET)) return get_net(old_net); ucounts = inc_net_namespaces(user_ns); if (!ucounts) return ERR_PTR(-ENFILE); net = net_alloc(); if (!net) if (!net) { dec_net_namespaces(ucounts); return ERR_PTR(-ENOMEM); } get_user_ns(user_ns); mutex_lock(&net_mutex); net->ucounts = ucounts; rv = setup_net(net, user_ns); if (rv == 0) { rtnl_lock(); Loading @@ -372,6 +390,7 @@ struct net *copy_net_ns(unsigned long flags, } mutex_unlock(&net_mutex); if (rv < 0) { dec_net_namespaces(ucounts); put_user_ns(user_ns); net_drop_ns(net); return ERR_PTR(rv); Loading Loading @@ -444,6 +463,7 @@ static void cleanup_net(struct work_struct *work) /* Finally it is safe to free my network namespace structure */ list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { list_del_init(&net->exit_list); dec_net_namespaces(net->ucounts); put_user_ns(net->user_ns); net_drop_ns(net); } Loading