aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mqueue.c68
-rw-r--r--ipc/msg.c3
-rw-r--r--ipc/sem.c3
-rw-r--r--ipc/shm.c23
-rw-r--r--ipc/util.c3
-rw-r--r--ipc/util.h2
6 files changed, 56 insertions, 46 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index c8943b53d8e6..59302fc3643b 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -11,6 +11,7 @@
11 * This file is released under the GPL. 11 * This file is released under the GPL.
12 */ 12 */
13 13
14#include <linux/capability.h>
14#include <linux/init.h> 15#include <linux/init.h>
15#include <linux/pagemap.h> 16#include <linux/pagemap.h>
16#include <linux/file.h> 17#include <linux/file.h>
@@ -598,15 +599,16 @@ static int mq_attr_ok(struct mq_attr *attr)
598static struct file *do_create(struct dentry *dir, struct dentry *dentry, 599static struct file *do_create(struct dentry *dir, struct dentry *dentry,
599 int oflag, mode_t mode, struct mq_attr __user *u_attr) 600 int oflag, mode_t mode, struct mq_attr __user *u_attr)
600{ 601{
601 struct file *filp;
602 struct mq_attr attr; 602 struct mq_attr attr;
603 int ret; 603 int ret;
604 604
605 if (u_attr != NULL) { 605 if (u_attr) {
606 ret = -EFAULT;
606 if (copy_from_user(&attr, u_attr, sizeof(attr))) 607 if (copy_from_user(&attr, u_attr, sizeof(attr)))
607 return ERR_PTR(-EFAULT); 608 goto out;
609 ret = -EINVAL;
608 if (!mq_attr_ok(&attr)) 610 if (!mq_attr_ok(&attr))
609 return ERR_PTR(-EINVAL); 611 goto out;
610 /* store for use during create */ 612 /* store for use during create */
611 dentry->d_fsdata = &attr; 613 dentry->d_fsdata = &attr;
612 } 614 }
@@ -615,13 +617,14 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
615 ret = vfs_create(dir->d_inode, dentry, mode, NULL); 617 ret = vfs_create(dir->d_inode, dentry, mode, NULL);
616 dentry->d_fsdata = NULL; 618 dentry->d_fsdata = NULL;
617 if (ret) 619 if (ret)
618 return ERR_PTR(ret); 620 goto out;
619 621
620 filp = dentry_open(dentry, mqueue_mnt, oflag); 622 return dentry_open(dentry, mqueue_mnt, oflag);
621 if (!IS_ERR(filp))
622 dget(dentry);
623 623
624 return filp; 624out:
625 dput(dentry);
626 mntput(mqueue_mnt);
627 return ERR_PTR(ret);
625} 628}
626 629
627/* Opens existing queue */ 630/* Opens existing queue */
@@ -629,20 +632,20 @@ static struct file *do_open(struct dentry *dentry, int oflag)
629{ 632{
630static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, 633static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
631 MAY_READ | MAY_WRITE }; 634 MAY_READ | MAY_WRITE };
632 struct file *filp;
633 635
634 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) 636 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
637 dput(dentry);
638 mntput(mqueue_mnt);
635 return ERR_PTR(-EINVAL); 639 return ERR_PTR(-EINVAL);
640 }
636 641
637 if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) 642 if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) {
643 dput(dentry);
644 mntput(mqueue_mnt);
638 return ERR_PTR(-EACCES); 645 return ERR_PTR(-EACCES);
646 }
639 647
640 filp = dentry_open(dentry, mqueue_mnt, oflag); 648 return dentry_open(dentry, mqueue_mnt, oflag);
641
642 if (!IS_ERR(filp))
643 dget(dentry);
644
645 return filp;
646} 649}
647 650
648asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, 651asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
@@ -660,7 +663,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
660 if (fd < 0) 663 if (fd < 0)
661 goto out_putname; 664 goto out_putname;
662 665
663 down(&mqueue_mnt->mnt_root->d_inode->i_sem); 666 mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
664 dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); 667 dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name));
665 if (IS_ERR(dentry)) { 668 if (IS_ERR(dentry)) {
666 error = PTR_ERR(dentry); 669 error = PTR_ERR(dentry);
@@ -670,17 +673,20 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
670 673
671 if (oflag & O_CREAT) { 674 if (oflag & O_CREAT) {
672 if (dentry->d_inode) { /* entry already exists */ 675 if (dentry->d_inode) { /* entry already exists */
673 filp = (oflag & O_EXCL) ? ERR_PTR(-EEXIST) : 676 error = -EEXIST;
674 do_open(dentry, oflag); 677 if (oflag & O_EXCL)
678 goto out;
679 filp = do_open(dentry, oflag);
675 } else { 680 } else {
676 filp = do_create(mqueue_mnt->mnt_root, dentry, 681 filp = do_create(mqueue_mnt->mnt_root, dentry,
677 oflag, mode, u_attr); 682 oflag, mode, u_attr);
678 } 683 }
679 } else 684 } else {
680 filp = (dentry->d_inode) ? do_open(dentry, oflag) : 685 error = -ENOENT;
681 ERR_PTR(-ENOENT); 686 if (!dentry->d_inode)
682 687 goto out;
683 dput(dentry); 688 filp = do_open(dentry, oflag);
689 }
684 690
685 if (IS_ERR(filp)) { 691 if (IS_ERR(filp)) {
686 error = PTR_ERR(filp); 692 error = PTR_ERR(filp);
@@ -691,13 +697,15 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
691 fd_install(fd, filp); 697 fd_install(fd, filp);
692 goto out_upsem; 698 goto out_upsem;
693 699
694out_putfd: 700out:
701 dput(dentry);
695 mntput(mqueue_mnt); 702 mntput(mqueue_mnt);
703out_putfd:
696 put_unused_fd(fd); 704 put_unused_fd(fd);
697out_err: 705out_err:
698 fd = error; 706 fd = error;
699out_upsem: 707out_upsem:
700 up(&mqueue_mnt->mnt_root->d_inode->i_sem); 708 mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
701out_putname: 709out_putname:
702 putname(name); 710 putname(name);
703 return fd; 711 return fd;
@@ -714,7 +722,7 @@ asmlinkage long sys_mq_unlink(const char __user *u_name)
714 if (IS_ERR(name)) 722 if (IS_ERR(name))
715 return PTR_ERR(name); 723 return PTR_ERR(name);
716 724
717 down(&mqueue_mnt->mnt_root->d_inode->i_sem); 725 mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
718 dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); 726 dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name));
719 if (IS_ERR(dentry)) { 727 if (IS_ERR(dentry)) {
720 err = PTR_ERR(dentry); 728 err = PTR_ERR(dentry);
@@ -735,7 +743,7 @@ out_err:
735 dput(dentry); 743 dput(dentry);
736 744
737out_unlock: 745out_unlock:
738 up(&mqueue_mnt->mnt_root->d_inode->i_sem); 746 mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
739 putname(name); 747 putname(name);
740 if (inode) 748 if (inode)
741 iput(inode); 749 iput(inode);
diff --git a/ipc/msg.c b/ipc/msg.c
index d035bd2aba96..fbf757064a32 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -12,9 +12,10 @@
12 * 12 *
13 * mostly rewritten, threaded and wake-one semantics added 13 * mostly rewritten, threaded and wake-one semantics added
14 * MSGMAX limit removed, sysctl's added 14 * MSGMAX limit removed, sysctl's added
15 * (c) 1999 Manfred Spraul <manfreds@colorfullife.com> 15 * (c) 1999 Manfred Spraul <manfred@colorfullife.com>
16 */ 16 */
17 17
18#include <linux/capability.h>
18#include <linux/config.h> 19#include <linux/config.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <linux/msg.h> 21#include <linux/msg.h>
diff --git a/ipc/sem.c b/ipc/sem.c
index cb5bb2a5df96..31fd4027d2b5 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -56,7 +56,7 @@
56 * /proc/sysvipc/sem support (c) 1999 Dragos Acostachioaie <dragos@iname.com> 56 * /proc/sysvipc/sem support (c) 1999 Dragos Acostachioaie <dragos@iname.com>
57 * 57 *
58 * SMP-threaded, sysctl's added 58 * SMP-threaded, sysctl's added
59 * (c) 1999 Manfred Spraul <manfreds@colorfullife.com> 59 * (c) 1999 Manfred Spraul <manfred@colorfullife.com>
60 * Enforced range limit on SEM_UNDO 60 * Enforced range limit on SEM_UNDO
61 * (c) 2001 Red Hat Inc <alan@redhat.com> 61 * (c) 2001 Red Hat Inc <alan@redhat.com>
62 * Lockless wakeup 62 * Lockless wakeup
@@ -73,6 +73,7 @@
73#include <linux/security.h> 73#include <linux/security.h>
74#include <linux/syscalls.h> 74#include <linux/syscalls.h>
75#include <linux/audit.h> 75#include <linux/audit.h>
76#include <linux/capability.h>
76#include <linux/seq_file.h> 77#include <linux/seq_file.h>
77#include <asm/uaccess.h> 78#include <asm/uaccess.h>
78#include "util.h" 79#include "util.h"
diff --git a/ipc/shm.c b/ipc/shm.c
index 0ef4a1cf3e27..4c28d2d8e305 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -27,6 +27,7 @@
27#include <linux/security.h> 27#include <linux/security.h>
28#include <linux/syscalls.h> 28#include <linux/syscalls.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/capability.h>
30#include <linux/ptrace.h> 31#include <linux/ptrace.h>
31#include <linux/seq_file.h> 32#include <linux/seq_file.h>
32 33
@@ -34,8 +35,6 @@
34 35
35#include "util.h" 36#include "util.h"
36 37
37#define shm_flags shm_perm.mode
38
39static struct file_operations shm_file_operations; 38static struct file_operations shm_file_operations;
40static struct vm_operations_struct shm_vm_ops; 39static struct vm_operations_struct shm_vm_ops;
41 40
@@ -148,7 +147,7 @@ static void shm_close (struct vm_area_struct *shmd)
148 shp->shm_dtim = get_seconds(); 147 shp->shm_dtim = get_seconds();
149 shp->shm_nattch--; 148 shp->shm_nattch--;
150 if(shp->shm_nattch == 0 && 149 if(shp->shm_nattch == 0 &&
151 shp->shm_flags & SHM_DEST) 150 shp->shm_perm.mode & SHM_DEST)
152 shm_destroy (shp); 151 shm_destroy (shp);
153 else 152 else
154 shm_unlock(shp); 153 shm_unlock(shp);
@@ -205,7 +204,7 @@ static int newseg (key_t key, int shmflg, size_t size)
205 return -ENOMEM; 204 return -ENOMEM;
206 205
207 shp->shm_perm.key = key; 206 shp->shm_perm.key = key;
208 shp->shm_flags = (shmflg & S_IRWXUGO); 207 shp->shm_perm.mode = (shmflg & S_IRWXUGO);
209 shp->mlock_user = NULL; 208 shp->mlock_user = NULL;
210 209
211 shp->shm_perm.security = NULL; 210 shp->shm_perm.security = NULL;
@@ -345,7 +344,7 @@ static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void __
345 344
346 out->uid = tbuf.shm_perm.uid; 345 out->uid = tbuf.shm_perm.uid;
347 out->gid = tbuf.shm_perm.gid; 346 out->gid = tbuf.shm_perm.gid;
348 out->mode = tbuf.shm_flags; 347 out->mode = tbuf.shm_perm.mode;
349 348
350 return 0; 349 return 0;
351 } 350 }
@@ -358,7 +357,7 @@ static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void __
358 357
359 out->uid = tbuf_old.shm_perm.uid; 358 out->uid = tbuf_old.shm_perm.uid;
360 out->gid = tbuf_old.shm_perm.gid; 359 out->gid = tbuf_old.shm_perm.gid;
361 out->mode = tbuf_old.shm_flags; 360 out->mode = tbuf_old.shm_perm.mode;
362 361
363 return 0; 362 return 0;
364 } 363 }
@@ -560,13 +559,13 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
560 if (!is_file_hugepages(shp->shm_file)) { 559 if (!is_file_hugepages(shp->shm_file)) {
561 err = shmem_lock(shp->shm_file, 1, user); 560 err = shmem_lock(shp->shm_file, 1, user);
562 if (!err) { 561 if (!err) {
563 shp->shm_flags |= SHM_LOCKED; 562 shp->shm_perm.mode |= SHM_LOCKED;
564 shp->mlock_user = user; 563 shp->mlock_user = user;
565 } 564 }
566 } 565 }
567 } else if (!is_file_hugepages(shp->shm_file)) { 566 } else if (!is_file_hugepages(shp->shm_file)) {
568 shmem_lock(shp->shm_file, 0, shp->mlock_user); 567 shmem_lock(shp->shm_file, 0, shp->mlock_user);
569 shp->shm_flags &= ~SHM_LOCKED; 568 shp->shm_perm.mode &= ~SHM_LOCKED;
570 shp->mlock_user = NULL; 569 shp->mlock_user = NULL;
571 } 570 }
572 shm_unlock(shp); 571 shm_unlock(shp);
@@ -605,7 +604,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
605 goto out_unlock_up; 604 goto out_unlock_up;
606 605
607 if (shp->shm_nattch){ 606 if (shp->shm_nattch){
608 shp->shm_flags |= SHM_DEST; 607 shp->shm_perm.mode |= SHM_DEST;
609 /* Do not find it any more */ 608 /* Do not find it any more */
610 shp->shm_perm.key = IPC_PRIVATE; 609 shp->shm_perm.key = IPC_PRIVATE;
611 shm_unlock(shp); 610 shm_unlock(shp);
@@ -644,7 +643,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
644 643
645 shp->shm_perm.uid = setbuf.uid; 644 shp->shm_perm.uid = setbuf.uid;
646 shp->shm_perm.gid = setbuf.gid; 645 shp->shm_perm.gid = setbuf.gid;
647 shp->shm_flags = (shp->shm_flags & ~S_IRWXUGO) 646 shp->shm_perm.mode = (shp->shm_perm.mode & ~S_IRWXUGO)
648 | (setbuf.mode & S_IRWXUGO); 647 | (setbuf.mode & S_IRWXUGO);
649 shp->shm_ctim = get_seconds(); 648 shp->shm_ctim = get_seconds();
650 break; 649 break;
@@ -777,7 +776,7 @@ invalid:
777 BUG(); 776 BUG();
778 shp->shm_nattch--; 777 shp->shm_nattch--;
779 if(shp->shm_nattch == 0 && 778 if(shp->shm_nattch == 0 &&
780 shp->shm_flags & SHM_DEST) 779 shp->shm_perm.mode & SHM_DEST)
781 shm_destroy (shp); 780 shm_destroy (shp);
782 else 781 else
783 shm_unlock(shp); 782 shm_unlock(shp);
@@ -902,7 +901,7 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
902 return seq_printf(s, format, 901 return seq_printf(s, format,
903 shp->shm_perm.key, 902 shp->shm_perm.key,
904 shp->id, 903 shp->id,
905 shp->shm_flags, 904 shp->shm_perm.mode,
906 shp->shm_segsz, 905 shp->shm_segsz,
907 shp->shm_cprid, 906 shp->shm_cprid,
908 shp->shm_lprid, 907 shp->shm_lprid,
diff --git a/ipc/util.c b/ipc/util.c
index 23f1cec150c1..862621980b01 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -7,7 +7,7 @@
7 * Occurs in several places in the IPC code. 7 * Occurs in several places in the IPC code.
8 * Chris Evans, <chris@ferret.lmh.ox.ac.uk> 8 * Chris Evans, <chris@ferret.lmh.ox.ac.uk>
9 * Nov 1999 - ipc helper functions, unified SMP locking 9 * Nov 1999 - ipc helper functions, unified SMP locking
10 * Manfred Spraul <manfreds@colorfullife.com> 10 * Manfred Spraul <manfred@colorfullife.com>
11 * Oct 2002 - One lock per IPC id. RCU ipc_free for lock-free grow_ary(). 11 * Oct 2002 - One lock per IPC id. RCU ipc_free for lock-free grow_ary().
12 * Mingming Cao <cmm@us.ibm.com> 12 * Mingming Cao <cmm@us.ibm.com>
13 */ 13 */
@@ -20,6 +20,7 @@
20#include <linux/smp_lock.h> 20#include <linux/smp_lock.h>
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/capability.h>
23#include <linux/highuid.h> 24#include <linux/highuid.h>
24#include <linux/security.h> 25#include <linux/security.h>
25#include <linux/rcupdate.h> 26#include <linux/rcupdate.h>
diff --git a/ipc/util.h b/ipc/util.h
index fc9a28be0797..efaff3ee7de7 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -2,7 +2,7 @@
2 * linux/ipc/util.h 2 * linux/ipc/util.h
3 * Copyright (C) 1999 Christoph Rohland 3 * Copyright (C) 1999 Christoph Rohland
4 * 4 *
5 * ipc helper functions (c) 1999 Manfred Spraul <manfreds@colorfullife.com> 5 * ipc helper functions (c) 1999 Manfred Spraul <manfred@colorfullife.com>
6 */ 6 */
7 7
8#ifndef _IPC_UTIL_H 8#ifndef _IPC_UTIL_H