diff options
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/mqueue.c | 15 | ||||
-rw-r--r-- | ipc/msg.c | 7 | ||||
-rw-r--r-- | ipc/msgutil.c | 3 | ||||
-rw-r--r-- | ipc/util.c | 15 |
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); | ||
844 | out_putname: | 853 | out_putname: |
845 | putname(name); | 854 | putname(name); |
846 | return fd; | 855 | return fd; |
@@ -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, ©_number); | 828 | copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax), |
829 | msgflg, &msgtyp, ©_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 | |||
52 | static void ipc_memory_notifier(struct work_struct *work) | 51 | static void ipc_memory_notifier(struct work_struct *work) |
53 | { | 52 | { |
54 | ipcns_notify(IPCNS_MEMCHANGED); | 53 | ipcns_notify(IPCNS_MEMCHANGED); |
55 | } | 54 | } |
56 | 55 | ||
57 | static DECLARE_WORK(ipc_memory_wq, ipc_memory_notifier); | ||
58 | |||
59 | |||
60 | static int ipc_memory_callback(struct notifier_block *self, | 56 | static 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 */ | 86 | static 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 | } |