mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-04-05 13:54:54 +00:00
netns: Add a limit on the number of net namespaces
Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
This commit is contained in:
parent
d08311dd6f
commit
703286608a
4 changed files with 24 additions and 1 deletions
|
@ -29,6 +29,7 @@ enum ucount_type {
|
||||||
UCOUNT_PID_NAMESPACES,
|
UCOUNT_PID_NAMESPACES,
|
||||||
UCOUNT_UTS_NAMESPACES,
|
UCOUNT_UTS_NAMESPACES,
|
||||||
UCOUNT_IPC_NAMESPACES,
|
UCOUNT_IPC_NAMESPACES,
|
||||||
|
UCOUNT_NET_NAMESPACES,
|
||||||
UCOUNT_CGROUP_NAMESPACES,
|
UCOUNT_CGROUP_NAMESPACES,
|
||||||
UCOUNT_COUNTS,
|
UCOUNT_COUNTS,
|
||||||
};
|
};
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct net {
|
||||||
struct list_head exit_list; /* Use only net_mutex */
|
struct list_head exit_list; /* Use only net_mutex */
|
||||||
|
|
||||||
struct user_namespace *user_ns; /* Owning user namespace */
|
struct user_namespace *user_ns; /* Owning user namespace */
|
||||||
|
struct ucounts *ucounts;
|
||||||
spinlock_t nsid_lock;
|
spinlock_t nsid_lock;
|
||||||
struct idr netns_ids;
|
struct idr netns_ids;
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ static struct ctl_table user_table[] = {
|
||||||
UCOUNT_ENTRY("max_pid_namespaces"),
|
UCOUNT_ENTRY("max_pid_namespaces"),
|
||||||
UCOUNT_ENTRY("max_uts_namespaces"),
|
UCOUNT_ENTRY("max_uts_namespaces"),
|
||||||
UCOUNT_ENTRY("max_ipc_namespaces"),
|
UCOUNT_ENTRY("max_ipc_namespaces"),
|
||||||
|
UCOUNT_ENTRY("max_net_namespaces"),
|
||||||
UCOUNT_ENTRY("max_cgroup_namespaces"),
|
UCOUNT_ENTRY("max_cgroup_namespaces"),
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
|
@ -266,6 +266,16 @@ struct net *get_net_ns_by_id(struct net *net, int id)
|
||||||
return peer;
|
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.
|
* setup_net runs the initializers for the network namespace object.
|
||||||
*/
|
*/
|
||||||
|
@ -351,19 +361,27 @@ void net_drop_ns(void *p)
|
||||||
struct net *copy_net_ns(unsigned long flags,
|
struct net *copy_net_ns(unsigned long flags,
|
||||||
struct user_namespace *user_ns, struct net *old_net)
|
struct user_namespace *user_ns, struct net *old_net)
|
||||||
{
|
{
|
||||||
|
struct ucounts *ucounts;
|
||||||
struct net *net;
|
struct net *net;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (!(flags & CLONE_NEWNET))
|
if (!(flags & CLONE_NEWNET))
|
||||||
return get_net(old_net);
|
return get_net(old_net);
|
||||||
|
|
||||||
|
ucounts = inc_net_namespaces(user_ns);
|
||||||
|
if (!ucounts)
|
||||||
|
return ERR_PTR(-ENFILE);
|
||||||
|
|
||||||
net = net_alloc();
|
net = net_alloc();
|
||||||
if (!net)
|
if (!net) {
|
||||||
|
dec_net_namespaces(ucounts);
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
get_user_ns(user_ns);
|
get_user_ns(user_ns);
|
||||||
|
|
||||||
mutex_lock(&net_mutex);
|
mutex_lock(&net_mutex);
|
||||||
|
net->ucounts = ucounts;
|
||||||
rv = setup_net(net, user_ns);
|
rv = setup_net(net, user_ns);
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
|
@ -372,6 +390,7 @@ struct net *copy_net_ns(unsigned long flags,
|
||||||
}
|
}
|
||||||
mutex_unlock(&net_mutex);
|
mutex_unlock(&net_mutex);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
|
dec_net_namespaces(ucounts);
|
||||||
put_user_ns(user_ns);
|
put_user_ns(user_ns);
|
||||||
net_drop_ns(net);
|
net_drop_ns(net);
|
||||||
return ERR_PTR(rv);
|
return ERR_PTR(rv);
|
||||||
|
@ -444,6 +463,7 @@ static void cleanup_net(struct work_struct *work)
|
||||||
/* Finally it is safe to free my network namespace structure */
|
/* Finally it is safe to free my network namespace structure */
|
||||||
list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
|
list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
|
||||||
list_del_init(&net->exit_list);
|
list_del_init(&net->exit_list);
|
||||||
|
dec_net_namespaces(net->ucounts);
|
||||||
put_user_ns(net->user_ns);
|
put_user_ns(net->user_ns);
|
||||||
net_drop_ns(net);
|
net_drop_ns(net);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue