aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-06 12:48:31 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-06 12:48:31 -0400
commitc87985a3ce723995fc7b25e598238d67154108a1 (patch)
treee60def1b77c25c1d74180f62e8a5603f9826f209 /ipc
parentd155255a344c417acad74156654295a2964e6b81 (diff)
parent0d7614f09c1ebdbaa1599a5aba7593f147bf96ee (diff)
Merge tty-next into 3.6-rc1
This handles the merge issue in: arch/um/drivers/line.c arch/um/drivers/line.h And resolves the duplicate patches that were in both trees do to the tty-next branch not getting merged into 3.6-rc1. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'ipc')
-rw-r--r--ipc/compat.c18
-rw-r--r--ipc/mqueue.c119
-rw-r--r--ipc/shm.c9
-rw-r--r--ipc/syscall.c2
-rw-r--r--ipc/util.c4
-rw-r--r--ipc/util.h2
6 files changed, 68 insertions, 86 deletions
diff --git a/ipc/compat.c b/ipc/compat.c
index a6df704f521e..ad9518eb26e0 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -118,7 +118,7 @@ extern int sem_ctls[];
118 118
119static inline int compat_ipc_parse_version(int *cmd) 119static inline int compat_ipc_parse_version(int *cmd)
120{ 120{
121#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC 121#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
122 int version = *cmd & IPC_64; 122 int version = *cmd & IPC_64;
123 123
124 /* this is tricky: architectures that have support for the old 124 /* this is tricky: architectures that have support for the old
@@ -373,21 +373,21 @@ long compat_sys_semctl(int semid, int semnum, int cmd, int arg)
373} 373}
374 374
375long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp, 375long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp,
376 size_t msgsz, int msgflg) 376 compat_ssize_t msgsz, int msgflg)
377{ 377{
378 compat_long_t mtype; 378 compat_long_t mtype;
379 379
380 if (get_user(mtype, &msgp->mtype)) 380 if (get_user(mtype, &msgp->mtype))
381 return -EFAULT; 381 return -EFAULT;
382 return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); 382 return do_msgsnd(msqid, mtype, msgp->mtext, (ssize_t)msgsz, msgflg);
383} 383}
384 384
385long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, 385long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp,
386 size_t msgsz, long msgtyp, int msgflg) 386 compat_ssize_t msgsz, long msgtyp, int msgflg)
387{ 387{
388 long err, mtype; 388 long err, mtype;
389 389
390 err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg); 390 err = do_msgrcv(msqid, &mtype, msgp->mtext, (ssize_t)msgsz, msgtyp, msgflg);
391 if (err < 0) 391 if (err < 0)
392 goto out; 392 goto out;
393 393
@@ -514,6 +514,10 @@ long compat_sys_msgctl(int first, int second, void __user *uptr)
514 return err; 514 return err;
515} 515}
516 516
517#ifndef COMPAT_SHMLBA
518#define COMPAT_SHMLBA SHMLBA
519#endif
520
517#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC 521#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
518long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, 522long compat_sys_shmat(int first, int second, compat_uptr_t third, int version,
519 void __user *uptr) 523 void __user *uptr)
@@ -524,7 +528,7 @@ long compat_sys_shmat(int first, int second, compat_uptr_t third, int version,
524 528
525 if (version == 1) 529 if (version == 1)
526 return -EINVAL; 530 return -EINVAL;
527 err = do_shmat(first, uptr, second, &raddr); 531 err = do_shmat(first, uptr, second, &raddr, COMPAT_SHMLBA);
528 if (err < 0) 532 if (err < 0)
529 return err; 533 return err;
530 uaddr = compat_ptr(third); 534 uaddr = compat_ptr(third);
@@ -536,7 +540,7 @@ long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg)
536 unsigned long ret; 540 unsigned long ret;
537 long err; 541 long err;
538 542
539 err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret); 543 err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret, COMPAT_SHMLBA);
540 if (err) 544 if (err)
541 return err; 545 return err;
542 force_successful_syscall_return(); 546 force_successful_syscall_return();
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 8ce57691e7b6..f8e54f5b9080 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -413,7 +413,7 @@ static void mqueue_evict_inode(struct inode *inode)
413} 413}
414 414
415static int mqueue_create(struct inode *dir, struct dentry *dentry, 415static int mqueue_create(struct inode *dir, struct dentry *dentry,
416 umode_t mode, struct nameidata *nd) 416 umode_t mode, bool excl)
417{ 417{
418 struct inode *inode; 418 struct inode *inode;
419 struct mq_attr *attr = dentry->d_fsdata; 419 struct mq_attr *attr = dentry->d_fsdata;
@@ -721,8 +721,8 @@ static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr)
721/* 721/*
722 * Invoked when creating a new queue via sys_mq_open 722 * Invoked when creating a new queue via sys_mq_open
723 */ 723 */
724static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir, 724static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir,
725 struct dentry *dentry, int oflag, umode_t mode, 725 struct path *path, int oflag, umode_t mode,
726 struct mq_attr *attr) 726 struct mq_attr *attr)
727{ 727{
728 const struct cred *cred = current_cred(); 728 const struct cred *cred = current_cred();
@@ -732,9 +732,9 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
732 if (attr) { 732 if (attr) {
733 ret = mq_attr_ok(ipc_ns, attr); 733 ret = mq_attr_ok(ipc_ns, attr);
734 if (ret) 734 if (ret)
735 goto out; 735 return ERR_PTR(ret);
736 /* store for use during create */ 736 /* store for use during create */
737 dentry->d_fsdata = attr; 737 path->dentry->d_fsdata = attr;
738 } else { 738 } else {
739 struct mq_attr def_attr; 739 struct mq_attr def_attr;
740 740
@@ -744,71 +744,51 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
744 ipc_ns->mq_msgsize_default); 744 ipc_ns->mq_msgsize_default);
745 ret = mq_attr_ok(ipc_ns, &def_attr); 745 ret = mq_attr_ok(ipc_ns, &def_attr);
746 if (ret) 746 if (ret)
747 goto out; 747 return ERR_PTR(ret);
748 } 748 }
749 749
750 mode &= ~current_umask(); 750 mode &= ~current_umask();
751 ret = mnt_want_write(ipc_ns->mq_mnt); 751 ret = mnt_want_write(path->mnt);
752 if (ret) 752 if (ret)
753 goto out; 753 return ERR_PTR(ret);
754 ret = vfs_create(dir->d_inode, dentry, mode, NULL); 754 ret = vfs_create(dir, path->dentry, mode, true);
755 dentry->d_fsdata = NULL; 755 path->dentry->d_fsdata = NULL;
756 if (ret) 756 if (!ret)
757 goto out_drop_write; 757 result = dentry_open(path, oflag, cred);
758 758 else
759 result = dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred); 759 result = ERR_PTR(ret);
760 /* 760 /*
761 * dentry_open() took a persistent mnt_want_write(), 761 * dentry_open() took a persistent mnt_want_write(),
762 * so we can now drop this one. 762 * so we can now drop this one.
763 */ 763 */
764 mnt_drop_write(ipc_ns->mq_mnt); 764 mnt_drop_write(path->mnt);
765 return result; 765 return result;
766
767out_drop_write:
768 mnt_drop_write(ipc_ns->mq_mnt);
769out:
770 dput(dentry);
771 mntput(ipc_ns->mq_mnt);
772 return ERR_PTR(ret);
773} 766}
774 767
775/* Opens existing queue */ 768/* Opens existing queue */
776static struct file *do_open(struct ipc_namespace *ipc_ns, 769static struct file *do_open(struct path *path, int oflag)
777 struct dentry *dentry, int oflag)
778{ 770{
779 int ret;
780 const struct cred *cred = current_cred();
781
782 static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, 771 static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
783 MAY_READ | MAY_WRITE }; 772 MAY_READ | MAY_WRITE };
784 773 int acc;
785 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { 774 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY))
786 ret = -EINVAL; 775 return ERR_PTR(-EINVAL);
787 goto err; 776 acc = oflag2acc[oflag & O_ACCMODE];
788 } 777 if (inode_permission(path->dentry->d_inode, acc))
789 778 return ERR_PTR(-EACCES);
790 if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { 779 return dentry_open(path, oflag, current_cred());
791 ret = -EACCES;
792 goto err;
793 }
794
795 return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
796
797err:
798 dput(dentry);
799 mntput(ipc_ns->mq_mnt);
800 return ERR_PTR(ret);
801} 780}
802 781
803SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, 782SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
804 struct mq_attr __user *, u_attr) 783 struct mq_attr __user *, u_attr)
805{ 784{
806 struct dentry *dentry; 785 struct path path;
807 struct file *filp; 786 struct file *filp;
808 char *name; 787 char *name;
809 struct mq_attr attr; 788 struct mq_attr attr;
810 int fd, error; 789 int fd, error;
811 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; 790 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
791 struct dentry *root = ipc_ns->mq_mnt->mnt_root;
812 792
813 if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) 793 if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
814 return -EFAULT; 794 return -EFAULT;
@@ -822,52 +802,49 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
822 if (fd < 0) 802 if (fd < 0)
823 goto out_putname; 803 goto out_putname;
824 804
825 mutex_lock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex); 805 error = 0;
826 dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name)); 806 mutex_lock(&root->d_inode->i_mutex);
827 if (IS_ERR(dentry)) { 807 path.dentry = lookup_one_len(name, root, strlen(name));
828 error = PTR_ERR(dentry); 808 if (IS_ERR(path.dentry)) {
809 error = PTR_ERR(path.dentry);
829 goto out_putfd; 810 goto out_putfd;
830 } 811 }
831 mntget(ipc_ns->mq_mnt); 812 path.mnt = mntget(ipc_ns->mq_mnt);
832 813
833 if (oflag & O_CREAT) { 814 if (oflag & O_CREAT) {
834 if (dentry->d_inode) { /* entry already exists */ 815 if (path.dentry->d_inode) { /* entry already exists */
835 audit_inode(name, dentry); 816 audit_inode(name, path.dentry);
836 if (oflag & O_EXCL) { 817 if (oflag & O_EXCL) {
837 error = -EEXIST; 818 error = -EEXIST;
838 goto out; 819 goto out;
839 } 820 }
840 filp = do_open(ipc_ns, dentry, oflag); 821 filp = do_open(&path, oflag);
841 } else { 822 } else {
842 filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root, 823 filp = do_create(ipc_ns, root->d_inode,
843 dentry, oflag, mode, 824 &path, oflag, mode,
844 u_attr ? &attr : NULL); 825 u_attr ? &attr : NULL);
845 } 826 }
846 } else { 827 } else {
847 if (!dentry->d_inode) { 828 if (!path.dentry->d_inode) {
848 error = -ENOENT; 829 error = -ENOENT;
849 goto out; 830 goto out;
850 } 831 }
851 audit_inode(name, dentry); 832 audit_inode(name, path.dentry);
852 filp = do_open(ipc_ns, dentry, oflag); 833 filp = do_open(&path, oflag);
853 } 834 }
854 835
855 if (IS_ERR(filp)) { 836 if (!IS_ERR(filp))
837 fd_install(fd, filp);
838 else
856 error = PTR_ERR(filp); 839 error = PTR_ERR(filp);
857 goto out_putfd;
858 }
859
860 fd_install(fd, filp);
861 goto out_upsem;
862
863out: 840out:
864 dput(dentry); 841 path_put(&path);
865 mntput(ipc_ns->mq_mnt);
866out_putfd: 842out_putfd:
867 put_unused_fd(fd); 843 if (error) {
868 fd = error; 844 put_unused_fd(fd);
869out_upsem: 845 fd = error;
870 mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex); 846 }
847 mutex_unlock(&root->d_inode->i_mutex);
871out_putname: 848out_putname:
872 putname(name); 849 putname(name);
873 return fd; 850 return fd;
diff --git a/ipc/shm.c b/ipc/shm.c
index 41c1285d697a..00faa05cf72a 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -953,7 +953,8 @@ out:
953 * "raddr" thing points to kernel space, and there has to be a wrapper around 953 * "raddr" thing points to kernel space, and there has to be a wrapper around
954 * this. 954 * this.
955 */ 955 */
956long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) 956long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
957 unsigned long shmlba)
957{ 958{
958 struct shmid_kernel *shp; 959 struct shmid_kernel *shp;
959 unsigned long addr; 960 unsigned long addr;
@@ -973,9 +974,9 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
973 if (shmid < 0) 974 if (shmid < 0)
974 goto out; 975 goto out;
975 else if ((addr = (ulong)shmaddr)) { 976 else if ((addr = (ulong)shmaddr)) {
976 if (addr & (SHMLBA-1)) { 977 if (addr & (shmlba - 1)) {
977 if (shmflg & SHM_RND) 978 if (shmflg & SHM_RND)
978 addr &= ~(SHMLBA-1); /* round down */ 979 addr &= ~(shmlba - 1); /* round down */
979 else 980 else
980#ifndef __ARCH_FORCE_SHMLBA 981#ifndef __ARCH_FORCE_SHMLBA
981 if (addr & ~PAGE_MASK) 982 if (addr & ~PAGE_MASK)
@@ -1107,7 +1108,7 @@ SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
1107 unsigned long ret; 1108 unsigned long ret;
1108 long err; 1109 long err;
1109 1110
1110 err = do_shmat(shmid, shmaddr, shmflg, &ret); 1111 err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA);
1111 if (err) 1112 if (err)
1112 return err; 1113 return err;
1113 force_successful_syscall_return(); 1114 force_successful_syscall_return();
diff --git a/ipc/syscall.c b/ipc/syscall.c
index 1d6f53f6b562..0d1e32ce048e 100644
--- a/ipc/syscall.c
+++ b/ipc/syscall.c
@@ -73,7 +73,7 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
73 default: { 73 default: {
74 unsigned long raddr; 74 unsigned long raddr;
75 ret = do_shmat(first, (char __user *)ptr, 75 ret = do_shmat(first, (char __user *)ptr,
76 second, &raddr); 76 second, &raddr, SHMLBA);
77 if (ret) 77 if (ret)
78 return ret; 78 return ret;
79 return put_user(raddr, (unsigned long __user *) third); 79 return put_user(raddr, (unsigned long __user *) third);
diff --git a/ipc/util.c b/ipc/util.c
index 75261a31d48d..eb07fd356f27 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -804,7 +804,7 @@ out_up:
804 return ERR_PTR(err); 804 return ERR_PTR(err);
805} 805}
806 806
807#ifdef __ARCH_WANT_IPC_PARSE_VERSION 807#ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
808 808
809 809
810/** 810/**
@@ -826,7 +826,7 @@ int ipc_parse_version (int *cmd)
826 } 826 }
827} 827}
828 828
829#endif /* __ARCH_WANT_IPC_PARSE_VERSION */ 829#endif /* CONFIG_ARCH_WANT_IPC_PARSE_VERSION */
830 830
831#ifdef CONFIG_PROC_FS 831#ifdef CONFIG_PROC_FS
832struct ipc_proc_iter { 832struct ipc_proc_iter {
diff --git a/ipc/util.h b/ipc/util.h
index 6f5c20bedaab..850ef3e962cb 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -130,7 +130,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
130 struct ipc_ids *ids, int id, int cmd, 130 struct ipc_ids *ids, int id, int cmd,
131 struct ipc64_perm *perm, int extra_perm); 131 struct ipc64_perm *perm, int extra_perm);
132 132
133#ifndef __ARCH_WANT_IPC_PARSE_VERSION 133#ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
134 /* On IA-64, we always use the "64-bit version" of the IPC structures. */ 134 /* On IA-64, we always use the "64-bit version" of the IPC structures. */
135# define ipc_parse_version(cmd) IPC_64 135# define ipc_parse_version(cmd) IPC_64
136#else 136#else