diff options
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/mqueue.c | 3 | ||||
-rw-r--r-- | ipc/shm.c | 260 | ||||
-rw-r--r-- | ipc/util.c | 7 |
3 files changed, 184 insertions, 86 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 0b5ecbe5f045..554ac368be79 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -731,7 +731,8 @@ asmlinkage long sys_mq_unlink(const char __user *u_name) | |||
731 | if (IS_ERR(name)) | 731 | if (IS_ERR(name)) |
732 | return PTR_ERR(name); | 732 | return PTR_ERR(name); |
733 | 733 | ||
734 | mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex); | 734 | mutex_lock_nested(&mqueue_mnt->mnt_root->d_inode->i_mutex, |
735 | I_MUTEX_PARENT); | ||
735 | dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); | 736 | dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); |
736 | if (IS_ERR(dentry)) { | 737 | if (IS_ERR(dentry)) { |
737 | err = PTR_ERR(dentry); | 738 | err = PTR_ERR(dentry); |
@@ -37,11 +37,21 @@ | |||
37 | #include <linux/seq_file.h> | 37 | #include <linux/seq_file.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/nsproxy.h> | 39 | #include <linux/nsproxy.h> |
40 | #include <linux/mount.h> | ||
40 | 41 | ||
41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
42 | 43 | ||
43 | #include "util.h" | 44 | #include "util.h" |
44 | 45 | ||
46 | struct shm_file_data { | ||
47 | int id; | ||
48 | struct ipc_namespace *ns; | ||
49 | struct file *file; | ||
50 | const struct vm_operations_struct *vm_ops; | ||
51 | }; | ||
52 | |||
53 | #define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data)) | ||
54 | |||
45 | static const struct file_operations shm_file_operations; | 55 | static const struct file_operations shm_file_operations; |
46 | static struct vm_operations_struct shm_vm_ops; | 56 | static struct vm_operations_struct shm_vm_ops; |
47 | 57 | ||
@@ -60,8 +70,8 @@ static struct ipc_ids init_shm_ids; | |||
60 | 70 | ||
61 | static int newseg (struct ipc_namespace *ns, key_t key, | 71 | static int newseg (struct ipc_namespace *ns, key_t key, |
62 | int shmflg, size_t size); | 72 | int shmflg, size_t size); |
63 | static void shm_open (struct vm_area_struct *shmd); | 73 | static void shm_open(struct vm_area_struct *vma); |
64 | static void shm_close (struct vm_area_struct *shmd); | 74 | static void shm_close(struct vm_area_struct *vma); |
65 | static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp); | 75 | static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp); |
66 | #ifdef CONFIG_PROC_FS | 76 | #ifdef CONFIG_PROC_FS |
67 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it); | 77 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it); |
@@ -150,11 +160,14 @@ static inline int shm_addid(struct ipc_namespace *ns, struct shmid_kernel *shp) | |||
150 | 160 | ||
151 | 161 | ||
152 | 162 | ||
153 | static inline void shm_inc(struct ipc_namespace *ns, int id) | 163 | /* This is called by fork, once for every shm attach. */ |
164 | static void shm_open(struct vm_area_struct *vma) | ||
154 | { | 165 | { |
166 | struct file *file = vma->vm_file; | ||
167 | struct shm_file_data *sfd = shm_file_data(file); | ||
155 | struct shmid_kernel *shp; | 168 | struct shmid_kernel *shp; |
156 | 169 | ||
157 | shp = shm_lock(ns, id); | 170 | shp = shm_lock(sfd->ns, sfd->id); |
158 | BUG_ON(!shp); | 171 | BUG_ON(!shp); |
159 | shp->shm_atim = get_seconds(); | 172 | shp->shm_atim = get_seconds(); |
160 | shp->shm_lprid = current->tgid; | 173 | shp->shm_lprid = current->tgid; |
@@ -162,15 +175,6 @@ static inline void shm_inc(struct ipc_namespace *ns, int id) | |||
162 | shm_unlock(shp); | 175 | shm_unlock(shp); |
163 | } | 176 | } |
164 | 177 | ||
165 | #define shm_file_ns(file) (*((struct ipc_namespace **)&(file)->private_data)) | ||
166 | |||
167 | /* This is called by fork, once for every shm attach. */ | ||
168 | static void shm_open(struct vm_area_struct *shmd) | ||
169 | { | ||
170 | shm_inc(shm_file_ns(shmd->vm_file), | ||
171 | shmd->vm_file->f_path.dentry->d_inode->i_ino); | ||
172 | } | ||
173 | |||
174 | /* | 178 | /* |
175 | * shm_destroy - free the struct shmid_kernel | 179 | * shm_destroy - free the struct shmid_kernel |
176 | * | 180 | * |
@@ -195,23 +199,21 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) | |||
195 | } | 199 | } |
196 | 200 | ||
197 | /* | 201 | /* |
198 | * remove the attach descriptor shmd. | 202 | * remove the attach descriptor vma. |
199 | * free memory for segment if it is marked destroyed. | 203 | * free memory for segment if it is marked destroyed. |
200 | * The descriptor has already been removed from the current->mm->mmap list | 204 | * The descriptor has already been removed from the current->mm->mmap list |
201 | * and will later be kfree()d. | 205 | * and will later be kfree()d. |
202 | */ | 206 | */ |
203 | static void shm_close (struct vm_area_struct *shmd) | 207 | static void shm_close(struct vm_area_struct *vma) |
204 | { | 208 | { |
205 | struct file * file = shmd->vm_file; | 209 | struct file * file = vma->vm_file; |
206 | int id = file->f_path.dentry->d_inode->i_ino; | 210 | struct shm_file_data *sfd = shm_file_data(file); |
207 | struct shmid_kernel *shp; | 211 | struct shmid_kernel *shp; |
208 | struct ipc_namespace *ns; | 212 | struct ipc_namespace *ns = sfd->ns; |
209 | |||
210 | ns = shm_file_ns(file); | ||
211 | 213 | ||
212 | mutex_lock(&shm_ids(ns).mutex); | 214 | mutex_lock(&shm_ids(ns).mutex); |
213 | /* remove from the list of attaches of the shm segment */ | 215 | /* remove from the list of attaches of the shm segment */ |
214 | shp = shm_lock(ns, id); | 216 | shp = shm_lock(ns, sfd->id); |
215 | BUG_ON(!shp); | 217 | BUG_ON(!shp); |
216 | shp->shm_lprid = current->tgid; | 218 | shp->shm_lprid = current->tgid; |
217 | shp->shm_dtim = get_seconds(); | 219 | shp->shm_dtim = get_seconds(); |
@@ -224,46 +226,111 @@ static void shm_close (struct vm_area_struct *shmd) | |||
224 | mutex_unlock(&shm_ids(ns).mutex); | 226 | mutex_unlock(&shm_ids(ns).mutex); |
225 | } | 227 | } |
226 | 228 | ||
229 | static struct page *shm_nopage(struct vm_area_struct *vma, | ||
230 | unsigned long address, int *type) | ||
231 | { | ||
232 | struct file *file = vma->vm_file; | ||
233 | struct shm_file_data *sfd = shm_file_data(file); | ||
234 | |||
235 | return sfd->vm_ops->nopage(vma, address, type); | ||
236 | } | ||
237 | |||
238 | #ifdef CONFIG_NUMA | ||
239 | int shm_set_policy(struct vm_area_struct *vma, struct mempolicy *new) | ||
240 | { | ||
241 | struct file *file = vma->vm_file; | ||
242 | struct shm_file_data *sfd = shm_file_data(file); | ||
243 | int err = 0; | ||
244 | if (sfd->vm_ops->set_policy) | ||
245 | err = sfd->vm_ops->set_policy(vma, new); | ||
246 | return err; | ||
247 | } | ||
248 | |||
249 | struct mempolicy *shm_get_policy(struct vm_area_struct *vma, unsigned long addr) | ||
250 | { | ||
251 | struct file *file = vma->vm_file; | ||
252 | struct shm_file_data *sfd = shm_file_data(file); | ||
253 | struct mempolicy *pol = NULL; | ||
254 | |||
255 | if (sfd->vm_ops->get_policy) | ||
256 | pol = sfd->vm_ops->get_policy(vma, addr); | ||
257 | else | ||
258 | pol = vma->vm_policy; | ||
259 | return pol; | ||
260 | } | ||
261 | #endif | ||
262 | |||
227 | static int shm_mmap(struct file * file, struct vm_area_struct * vma) | 263 | static int shm_mmap(struct file * file, struct vm_area_struct * vma) |
228 | { | 264 | { |
265 | struct shm_file_data *sfd = shm_file_data(file); | ||
229 | int ret; | 266 | int ret; |
230 | 267 | ||
231 | ret = shmem_mmap(file, vma); | 268 | ret = sfd->file->f_op->mmap(sfd->file, vma); |
232 | if (ret == 0) { | 269 | if (ret != 0) |
233 | vma->vm_ops = &shm_vm_ops; | 270 | return ret; |
234 | if (!(vma->vm_flags & VM_WRITE)) | 271 | sfd->vm_ops = vma->vm_ops; |
235 | vma->vm_flags &= ~VM_MAYWRITE; | 272 | vma->vm_ops = &shm_vm_ops; |
236 | shm_inc(shm_file_ns(file), file->f_path.dentry->d_inode->i_ino); | 273 | shm_open(vma); |
237 | } | ||
238 | 274 | ||
239 | return ret; | 275 | return ret; |
240 | } | 276 | } |
241 | 277 | ||
242 | static int shm_release(struct inode *ino, struct file *file) | 278 | static int shm_release(struct inode *ino, struct file *file) |
243 | { | 279 | { |
244 | struct ipc_namespace *ns; | 280 | struct shm_file_data *sfd = shm_file_data(file); |
245 | 281 | ||
246 | ns = shm_file_ns(file); | 282 | put_ipc_ns(sfd->ns); |
247 | put_ipc_ns(ns); | 283 | shm_file_data(file) = NULL; |
248 | shm_file_ns(file) = NULL; | 284 | kfree(sfd); |
249 | return 0; | 285 | return 0; |
250 | } | 286 | } |
251 | 287 | ||
288 | static int shm_fsync(struct file *file, struct dentry *dentry, int datasync) | ||
289 | { | ||
290 | int (*fsync) (struct file *, struct dentry *, int datasync); | ||
291 | struct shm_file_data *sfd = shm_file_data(file); | ||
292 | int ret = -EINVAL; | ||
293 | |||
294 | fsync = sfd->file->f_op->fsync; | ||
295 | if (fsync) | ||
296 | ret = fsync(sfd->file, sfd->file->f_path.dentry, datasync); | ||
297 | return ret; | ||
298 | } | ||
299 | |||
300 | static unsigned long shm_get_unmapped_area(struct file *file, | ||
301 | unsigned long addr, unsigned long len, unsigned long pgoff, | ||
302 | unsigned long flags) | ||
303 | { | ||
304 | struct shm_file_data *sfd = shm_file_data(file); | ||
305 | return get_unmapped_area(sfd->file, addr, len, pgoff, flags); | ||
306 | } | ||
307 | |||
308 | int is_file_shm_hugepages(struct file *file) | ||
309 | { | ||
310 | int ret = 0; | ||
311 | |||
312 | if (file->f_op == &shm_file_operations) { | ||
313 | struct shm_file_data *sfd; | ||
314 | sfd = shm_file_data(file); | ||
315 | ret = is_file_hugepages(sfd->file); | ||
316 | } | ||
317 | return ret; | ||
318 | } | ||
319 | |||
252 | static const struct file_operations shm_file_operations = { | 320 | static const struct file_operations shm_file_operations = { |
253 | .mmap = shm_mmap, | 321 | .mmap = shm_mmap, |
322 | .fsync = shm_fsync, | ||
254 | .release = shm_release, | 323 | .release = shm_release, |
255 | #ifndef CONFIG_MMU | 324 | .get_unmapped_area = shm_get_unmapped_area, |
256 | .get_unmapped_area = shmem_get_unmapped_area, | ||
257 | #endif | ||
258 | }; | 325 | }; |
259 | 326 | ||
260 | static struct vm_operations_struct shm_vm_ops = { | 327 | static struct vm_operations_struct shm_vm_ops = { |
261 | .open = shm_open, /* callback for a new vm-area open */ | 328 | .open = shm_open, /* callback for a new vm-area open */ |
262 | .close = shm_close, /* callback for when the vm-area is released */ | 329 | .close = shm_close, /* callback for when the vm-area is released */ |
263 | .nopage = shmem_nopage, | 330 | .nopage = shm_nopage, |
264 | #if defined(CONFIG_NUMA) && defined(CONFIG_SHMEM) | 331 | #if defined(CONFIG_NUMA) |
265 | .set_policy = shmem_set_policy, | 332 | .set_policy = shm_set_policy, |
266 | .get_policy = shmem_get_policy, | 333 | .get_policy = shm_get_policy, |
267 | #endif | 334 | #endif |
268 | }; | 335 | }; |
269 | 336 | ||
@@ -330,13 +397,6 @@ static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size) | |||
330 | shp->shm_nattch = 0; | 397 | shp->shm_nattch = 0; |
331 | shp->id = shm_buildid(ns, id, shp->shm_perm.seq); | 398 | shp->id = shm_buildid(ns, id, shp->shm_perm.seq); |
332 | shp->shm_file = file; | 399 | shp->shm_file = file; |
333 | file->f_path.dentry->d_inode->i_ino = shp->id; | ||
334 | |||
335 | shm_file_ns(file) = get_ipc_ns(ns); | ||
336 | |||
337 | /* Hugetlb ops would have already been assigned. */ | ||
338 | if (!(shmflg & SHM_HUGETLB)) | ||
339 | file->f_op = &shm_file_operations; | ||
340 | 400 | ||
341 | ns->shm_tot += numpages; | 401 | ns->shm_tot += numpages; |
342 | shm_unlock(shp); | 402 | shm_unlock(shp); |
@@ -607,10 +667,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) | |||
607 | tbuf.shm_ctime = shp->shm_ctim; | 667 | tbuf.shm_ctime = shp->shm_ctim; |
608 | tbuf.shm_cpid = shp->shm_cprid; | 668 | tbuf.shm_cpid = shp->shm_cprid; |
609 | tbuf.shm_lpid = shp->shm_lprid; | 669 | tbuf.shm_lpid = shp->shm_lprid; |
610 | if (!is_file_hugepages(shp->shm_file)) | 670 | tbuf.shm_nattch = shp->shm_nattch; |
611 | tbuf.shm_nattch = shp->shm_nattch; | ||
612 | else | ||
613 | tbuf.shm_nattch = file_count(shp->shm_file) - 1; | ||
614 | shm_unlock(shp); | 671 | shm_unlock(shp); |
615 | if(copy_shmid_to_user (buf, &tbuf, version)) | 672 | if(copy_shmid_to_user (buf, &tbuf, version)) |
616 | err = -EFAULT; | 673 | err = -EFAULT; |
@@ -779,13 +836,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) | |||
779 | unsigned long flags; | 836 | unsigned long flags; |
780 | unsigned long prot; | 837 | unsigned long prot; |
781 | int acc_mode; | 838 | int acc_mode; |
782 | void *user_addr; | 839 | unsigned long user_addr; |
783 | struct ipc_namespace *ns; | 840 | struct ipc_namespace *ns; |
841 | struct shm_file_data *sfd; | ||
842 | struct path path; | ||
843 | mode_t f_mode; | ||
784 | 844 | ||
785 | if (shmid < 0) { | 845 | err = -EINVAL; |
786 | err = -EINVAL; | 846 | if (shmid < 0) |
787 | goto out; | 847 | goto out; |
788 | } else if ((addr = (ulong)shmaddr)) { | 848 | else if ((addr = (ulong)shmaddr)) { |
789 | if (addr & (SHMLBA-1)) { | 849 | if (addr & (SHMLBA-1)) { |
790 | if (shmflg & SHM_RND) | 850 | if (shmflg & SHM_RND) |
791 | addr &= ~(SHMLBA-1); /* round down */ | 851 | addr &= ~(SHMLBA-1); /* round down */ |
@@ -793,12 +853,12 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) | |||
793 | #ifndef __ARCH_FORCE_SHMLBA | 853 | #ifndef __ARCH_FORCE_SHMLBA |
794 | if (addr & ~PAGE_MASK) | 854 | if (addr & ~PAGE_MASK) |
795 | #endif | 855 | #endif |
796 | return -EINVAL; | 856 | goto out; |
797 | } | 857 | } |
798 | flags = MAP_SHARED | MAP_FIXED; | 858 | flags = MAP_SHARED | MAP_FIXED; |
799 | } else { | 859 | } else { |
800 | if ((shmflg & SHM_REMAP)) | 860 | if ((shmflg & SHM_REMAP)) |
801 | return -EINVAL; | 861 | goto out; |
802 | 862 | ||
803 | flags = MAP_SHARED; | 863 | flags = MAP_SHARED; |
804 | } | 864 | } |
@@ -806,9 +866,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) | |||
806 | if (shmflg & SHM_RDONLY) { | 866 | if (shmflg & SHM_RDONLY) { |
807 | prot = PROT_READ; | 867 | prot = PROT_READ; |
808 | acc_mode = S_IRUGO; | 868 | acc_mode = S_IRUGO; |
869 | f_mode = FMODE_READ; | ||
809 | } else { | 870 | } else { |
810 | prot = PROT_READ | PROT_WRITE; | 871 | prot = PROT_READ | PROT_WRITE; |
811 | acc_mode = S_IRUGO | S_IWUGO; | 872 | acc_mode = S_IRUGO | S_IWUGO; |
873 | f_mode = FMODE_READ | FMODE_WRITE; | ||
812 | } | 874 | } |
813 | if (shmflg & SHM_EXEC) { | 875 | if (shmflg & SHM_EXEC) { |
814 | prot |= PROT_EXEC; | 876 | prot |= PROT_EXEC; |
@@ -821,35 +883,50 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) | |||
821 | */ | 883 | */ |
822 | ns = current->nsproxy->ipc_ns; | 884 | ns = current->nsproxy->ipc_ns; |
823 | shp = shm_lock(ns, shmid); | 885 | shp = shm_lock(ns, shmid); |
824 | if(shp == NULL) { | 886 | if(shp == NULL) |
825 | err = -EINVAL; | ||
826 | goto out; | 887 | goto out; |
827 | } | 888 | |
828 | err = shm_checkid(ns, shp,shmid); | 889 | err = shm_checkid(ns, shp,shmid); |
829 | if (err) { | 890 | if (err) |
830 | shm_unlock(shp); | 891 | goto out_unlock; |
831 | goto out; | 892 | |
832 | } | 893 | err = -EACCES; |
833 | if (ipcperms(&shp->shm_perm, acc_mode)) { | 894 | if (ipcperms(&shp->shm_perm, acc_mode)) |
834 | shm_unlock(shp); | 895 | goto out_unlock; |
835 | err = -EACCES; | ||
836 | goto out; | ||
837 | } | ||
838 | 896 | ||
839 | err = security_shm_shmat(shp, shmaddr, shmflg); | 897 | err = security_shm_shmat(shp, shmaddr, shmflg); |
840 | if (err) { | 898 | if (err) |
841 | shm_unlock(shp); | 899 | goto out_unlock; |
842 | return err; | 900 | |
843 | } | 901 | path.dentry = dget(shp->shm_file->f_path.dentry); |
844 | 902 | path.mnt = mntget(shp->shm_file->f_path.mnt); | |
845 | file = shp->shm_file; | ||
846 | size = i_size_read(file->f_path.dentry->d_inode); | ||
847 | shp->shm_nattch++; | 903 | shp->shm_nattch++; |
904 | size = i_size_read(path.dentry->d_inode); | ||
848 | shm_unlock(shp); | 905 | shm_unlock(shp); |
849 | 906 | ||
907 | err = -ENOMEM; | ||
908 | sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); | ||
909 | if (!sfd) | ||
910 | goto out_put_path; | ||
911 | |||
912 | err = -ENOMEM; | ||
913 | file = get_empty_filp(); | ||
914 | if (!file) | ||
915 | goto out_free; | ||
916 | |||
917 | file->f_op = &shm_file_operations; | ||
918 | file->private_data = sfd; | ||
919 | file->f_path = path; | ||
920 | file->f_mapping = shp->shm_file->f_mapping; | ||
921 | file->f_mode = f_mode; | ||
922 | sfd->id = shp->id; | ||
923 | sfd->ns = get_ipc_ns(ns); | ||
924 | sfd->file = shp->shm_file; | ||
925 | sfd->vm_ops = NULL; | ||
926 | |||
850 | down_write(¤t->mm->mmap_sem); | 927 | down_write(¤t->mm->mmap_sem); |
851 | if (addr && !(shmflg & SHM_REMAP)) { | 928 | if (addr && !(shmflg & SHM_REMAP)) { |
852 | user_addr = ERR_PTR(-EINVAL); | 929 | err = -EINVAL; |
853 | if (find_vma_intersection(current->mm, addr, addr + size)) | 930 | if (find_vma_intersection(current->mm, addr, addr + size)) |
854 | goto invalid; | 931 | goto invalid; |
855 | /* | 932 | /* |
@@ -861,11 +938,17 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) | |||
861 | goto invalid; | 938 | goto invalid; |
862 | } | 939 | } |
863 | 940 | ||
864 | user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0); | 941 | user_addr = do_mmap (file, addr, size, prot, flags, 0); |
865 | 942 | *raddr = user_addr; | |
943 | err = 0; | ||
944 | if (IS_ERR_VALUE(user_addr)) | ||
945 | err = (long)user_addr; | ||
866 | invalid: | 946 | invalid: |
867 | up_write(¤t->mm->mmap_sem); | 947 | up_write(¤t->mm->mmap_sem); |
868 | 948 | ||
949 | fput(file); | ||
950 | |||
951 | out_nattch: | ||
869 | mutex_lock(&shm_ids(ns).mutex); | 952 | mutex_lock(&shm_ids(ns).mutex); |
870 | shp = shm_lock(ns, shmid); | 953 | shp = shm_lock(ns, shmid); |
871 | BUG_ON(!shp); | 954 | BUG_ON(!shp); |
@@ -877,12 +960,19 @@ invalid: | |||
877 | shm_unlock(shp); | 960 | shm_unlock(shp); |
878 | mutex_unlock(&shm_ids(ns).mutex); | 961 | mutex_unlock(&shm_ids(ns).mutex); |
879 | 962 | ||
880 | *raddr = (unsigned long) user_addr; | ||
881 | err = 0; | ||
882 | if (IS_ERR(user_addr)) | ||
883 | err = PTR_ERR(user_addr); | ||
884 | out: | 963 | out: |
885 | return err; | 964 | return err; |
965 | |||
966 | out_unlock: | ||
967 | shm_unlock(shp); | ||
968 | goto out; | ||
969 | |||
970 | out_free: | ||
971 | kfree(sfd); | ||
972 | out_put_path: | ||
973 | dput(path.dentry); | ||
974 | mntput(path.mnt); | ||
975 | goto out_nattch; | ||
886 | } | 976 | } |
887 | 977 | ||
888 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg) | 978 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg) |
@@ -944,7 +1034,7 @@ asmlinkage long sys_shmdt(char __user *shmaddr) | |||
944 | * a fragment created by mprotect() and/or munmap(), or it | 1034 | * a fragment created by mprotect() and/or munmap(), or it |
945 | * otherwise it starts at this address with no hassles. | 1035 | * otherwise it starts at this address with no hassles. |
946 | */ | 1036 | */ |
947 | if ((vma->vm_ops == &shm_vm_ops || is_vm_hugetlb_page(vma)) && | 1037 | if ((vma->vm_ops == &shm_vm_ops) && |
948 | (vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) { | 1038 | (vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) { |
949 | 1039 | ||
950 | 1040 | ||
@@ -973,7 +1063,7 @@ asmlinkage long sys_shmdt(char __user *shmaddr) | |||
973 | next = vma->vm_next; | 1063 | next = vma->vm_next; |
974 | 1064 | ||
975 | /* finding a matching vma now does not alter retval */ | 1065 | /* finding a matching vma now does not alter retval */ |
976 | if ((vma->vm_ops == &shm_vm_ops || is_vm_hugetlb_page(vma)) && | 1066 | if ((vma->vm_ops == &shm_vm_ops) && |
977 | (vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) | 1067 | (vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) |
978 | 1068 | ||
979 | do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); | 1069 | do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); |
@@ -1004,7 +1094,7 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it) | |||
1004 | shp->shm_segsz, | 1094 | shp->shm_segsz, |
1005 | shp->shm_cprid, | 1095 | shp->shm_cprid, |
1006 | shp->shm_lprid, | 1096 | shp->shm_lprid, |
1007 | is_file_hugepages(shp->shm_file) ? (file_count(shp->shm_file) - 1) : shp->shm_nattch, | 1097 | shp->shm_nattch, |
1008 | shp->shm_perm.uid, | 1098 | shp->shm_perm.uid, |
1009 | shp->shm_perm.gid, | 1099 | shp->shm_perm.gid, |
1010 | shp->shm_perm.cuid, | 1100 | shp->shm_perm.cuid, |
diff --git a/ipc/util.c b/ipc/util.c index 08a647965b9e..0b652387d169 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -144,6 +144,13 @@ void free_ipc_ns(struct kref *kref) | |||
144 | shm_exit_ns(ns); | 144 | shm_exit_ns(ns); |
145 | kfree(ns); | 145 | kfree(ns); |
146 | } | 146 | } |
147 | #else | ||
148 | int copy_ipcs(unsigned long flags, struct task_struct *tsk) | ||
149 | { | ||
150 | if (flags & CLONE_NEWIPC) | ||
151 | return -EINVAL; | ||
152 | return 0; | ||
153 | } | ||
147 | #endif | 154 | #endif |
148 | 155 | ||
149 | /** | 156 | /** |