aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mqueue.c15
-rw-r--r--ipc/msg.c7
-rw-r--r--ipc/msgutil.c3
-rw-r--r--ipc/util.c15
4 files changed, 25 insertions, 15 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index e5c4f609f22c..e4e47f647446 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -330,8 +330,16 @@ static struct dentry *mqueue_mount(struct file_system_type *fs_type,
330 int flags, const char *dev_name, 330 int flags, const char *dev_name,
331 void *data) 331 void *data)
332{ 332{
333 if (!(flags & MS_KERNMOUNT)) 333 if (!(flags & MS_KERNMOUNT)) {
334 data = current->nsproxy->ipc_ns; 334 struct ipc_namespace *ns = current->nsproxy->ipc_ns;
335 /* Don't allow mounting unless the caller has CAP_SYS_ADMIN
336 * over the ipc namespace.
337 */
338 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
339 return ERR_PTR(-EPERM);
340
341 data = ns;
342 }
335 return mount_ns(fs_type, flags, data, mqueue_fill_super); 343 return mount_ns(fs_type, flags, data, mqueue_fill_super);
336} 344}
337 345
@@ -840,7 +848,8 @@ out_putfd:
840 fd = error; 848 fd = error;
841 } 849 }
842 mutex_unlock(&root->d_inode->i_mutex); 850 mutex_unlock(&root->d_inode->i_mutex);
843 mnt_drop_write(mnt); 851 if (!ro)
852 mnt_drop_write(mnt);
844out_putname: 853out_putname:
845 putname(name); 854 putname(name);
846 return fd; 855 return fd;
diff --git a/ipc/msg.c b/ipc/msg.c
index 950572f9d796..fede1d06ef30 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -820,15 +820,17 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
820 struct msg_msg *copy = NULL; 820 struct msg_msg *copy = NULL;
821 unsigned long copy_number = 0; 821 unsigned long copy_number = 0;
822 822
823 ns = current->nsproxy->ipc_ns;
824
823 if (msqid < 0 || (long) bufsz < 0) 825 if (msqid < 0 || (long) bufsz < 0)
824 return -EINVAL; 826 return -EINVAL;
825 if (msgflg & MSG_COPY) { 827 if (msgflg & MSG_COPY) {
826 copy = prepare_copy(buf, bufsz, msgflg, &msgtyp, &copy_number); 828 copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax),
829 msgflg, &msgtyp, &copy_number);
827 if (IS_ERR(copy)) 830 if (IS_ERR(copy))
828 return PTR_ERR(copy); 831 return PTR_ERR(copy);
829 } 832 }
830 mode = convert_mode(&msgtyp, msgflg); 833 mode = convert_mode(&msgtyp, msgflg);
831 ns = current->nsproxy->ipc_ns;
832 834
833 msq = msg_lock_check(ns, msqid); 835 msq = msg_lock_check(ns, msqid);
834 if (IS_ERR(msq)) { 836 if (IS_ERR(msq)) {
@@ -870,6 +872,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
870 goto out_unlock; 872 goto out_unlock;
871 break; 873 break;
872 } 874 }
875 msg = ERR_PTR(-EAGAIN);
873 } else 876 } else
874 break; 877 break;
875 msg_counter++; 878 msg_counter++;
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index ebfcbfa8b7f2..5df8e4bf1db0 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -117,9 +117,6 @@ struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
117 if (alen > DATALEN_MSG) 117 if (alen > DATALEN_MSG)
118 alen = DATALEN_MSG; 118 alen = DATALEN_MSG;
119 119
120 dst->next = NULL;
121 dst->security = NULL;
122
123 memcpy(dst + 1, src + 1, alen); 120 memcpy(dst + 1, src + 1, alen);
124 121
125 len -= alen; 122 len -= alen;
diff --git a/ipc/util.c b/ipc/util.c
index 464a8abd779f..03eadd8fb0fd 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -23,6 +23,7 @@
23#include <linux/msg.h> 23#include <linux/msg.h>
24#include <linux/vmalloc.h> 24#include <linux/vmalloc.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/notifier.h>
26#include <linux/capability.h> 27#include <linux/capability.h>
27#include <linux/highuid.h> 28#include <linux/highuid.h>
28#include <linux/security.h> 29#include <linux/security.h>
@@ -47,19 +48,16 @@ struct ipc_proc_iface {
47 int (*show)(struct seq_file *, void *); 48 int (*show)(struct seq_file *, void *);
48}; 49};
49 50
50#ifdef CONFIG_MEMORY_HOTPLUG
51
52static void ipc_memory_notifier(struct work_struct *work) 51static void ipc_memory_notifier(struct work_struct *work)
53{ 52{
54 ipcns_notify(IPCNS_MEMCHANGED); 53 ipcns_notify(IPCNS_MEMCHANGED);
55} 54}
56 55
57static DECLARE_WORK(ipc_memory_wq, ipc_memory_notifier);
58
59
60static int ipc_memory_callback(struct notifier_block *self, 56static int ipc_memory_callback(struct notifier_block *self,
61 unsigned long action, void *arg) 57 unsigned long action, void *arg)
62{ 58{
59 static DECLARE_WORK(ipc_memory_wq, ipc_memory_notifier);
60
63 switch (action) { 61 switch (action) {
64 case MEM_ONLINE: /* memory successfully brought online */ 62 case MEM_ONLINE: /* memory successfully brought online */
65 case MEM_OFFLINE: /* or offline: it's time to recompute msgmni */ 63 case MEM_OFFLINE: /* or offline: it's time to recompute msgmni */
@@ -85,7 +83,10 @@ static int ipc_memory_callback(struct notifier_block *self,
85 return NOTIFY_OK; 83 return NOTIFY_OK;
86} 84}
87 85
88#endif /* CONFIG_MEMORY_HOTPLUG */ 86static struct notifier_block ipc_memory_nb = {
87 .notifier_call = ipc_memory_callback,
88 .priority = IPC_CALLBACK_PRI,
89};
89 90
90/** 91/**
91 * ipc_init - initialise IPC subsystem 92 * ipc_init - initialise IPC subsystem
@@ -102,7 +103,7 @@ static int __init ipc_init(void)
102 sem_init(); 103 sem_init();
103 msg_init(); 104 msg_init();
104 shm_init(); 105 shm_init();
105 hotplug_memory_notifier(ipc_memory_callback, IPC_CALLBACK_PRI); 106 register_hotmemory_notifier(&ipc_memory_nb);
106 register_ipcns_notifier(&init_ipc_ns); 107 register_ipcns_notifier(&init_ipc_ns);
107 return 0; 108 return 0;
108} 109}