Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipcns: Add a limit on the number of ipc namespaces

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>

+37 -11
+1
include/linux/ipc_namespace.h
··· 58 58 59 59 /* user_ns which owns the ipc ns */ 60 60 struct user_namespace *user_ns; 61 + struct ucounts *ucounts; 61 62 62 63 struct ns_common ns; 63 64 };
+1
include/linux/user_namespace.h
··· 28 28 UCOUNT_USER_NAMESPACES, 29 29 UCOUNT_PID_NAMESPACES, 30 30 UCOUNT_UTS_NAMESPACES, 31 + UCOUNT_IPC_NAMESPACES, 31 32 UCOUNT_COUNTS, 32 33 }; 33 34
+34 -11
ipc/namespace.c
··· 16 16 17 17 #include "util.h" 18 18 19 + static struct ucounts *inc_ipc_namespaces(struct user_namespace *ns) 20 + { 21 + return inc_ucount(ns, current_euid(), UCOUNT_IPC_NAMESPACES); 22 + } 23 + 24 + static void dec_ipc_namespaces(struct ucounts *ucounts) 25 + { 26 + dec_ucount(ucounts, UCOUNT_IPC_NAMESPACES); 27 + } 28 + 19 29 static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, 20 30 struct ipc_namespace *old_ns) 21 31 { 22 32 struct ipc_namespace *ns; 33 + struct ucounts *ucounts; 23 34 int err; 24 35 36 + err = -ENFILE; 37 + ucounts = inc_ipc_namespaces(user_ns); 38 + if (!ucounts) 39 + goto fail; 40 + 41 + err = -ENOMEM; 25 42 ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL); 26 43 if (ns == NULL) 27 - return ERR_PTR(-ENOMEM); 44 + goto fail_dec; 28 45 29 46 err = ns_alloc_inum(&ns->ns); 30 - if (err) { 31 - kfree(ns); 32 - return ERR_PTR(err); 33 - } 47 + if (err) 48 + goto fail_free; 34 49 ns->ns.ops = &ipcns_operations; 35 50 36 51 atomic_set(&ns->count, 1); 37 52 ns->user_ns = get_user_ns(user_ns); 53 + ns->ucounts = ucounts; 38 54 39 55 err = mq_init_ns(ns); 40 - if (err) { 41 - put_user_ns(ns->user_ns); 42 - ns_free_inum(&ns->ns); 43 - kfree(ns); 44 - return ERR_PTR(err); 45 - } 56 + if (err) 57 + goto fail_put; 46 58 47 59 sem_init_ns(ns); 48 60 msg_init_ns(ns); 49 61 shm_init_ns(ns); 50 62 51 63 return ns; 64 + 65 + fail_put: 66 + put_user_ns(ns->user_ns); 67 + ns_free_inum(&ns->ns); 68 + fail_free: 69 + kfree(ns); 70 + fail_dec: 71 + dec_ipc_namespaces(ucounts); 72 + fail: 73 + return ERR_PTR(err); 52 74 } 53 75 54 76 struct ipc_namespace *copy_ipcs(unsigned long flags, ··· 118 96 msg_exit_ns(ns); 119 97 shm_exit_ns(ns); 120 98 99 + dec_ipc_namespaces(ns->ucounts); 121 100 put_user_ns(ns->user_ns); 122 101 ns_free_inum(&ns->ns); 123 102 kfree(ns);
+1
kernel/ucount.c
··· 70 70 UCOUNT_ENTRY("max_user_namespaces"), 71 71 UCOUNT_ENTRY("max_pid_namespaces"), 72 72 UCOUNT_ENTRY("max_uts_namespaces"), 73 + UCOUNT_ENTRY("max_ipc_namespaces"), 73 74 { } 74 75 }; 75 76 #endif /* CONFIG_SYSCTL */