aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2009-02-05 19:01:45 -0500
committerJames Morris <jmorris@namei.org>2009-02-05 19:01:45 -0500
commitcb5629b10d64a8006622ce3a52bc887d91057d69 (patch)
tree7c06d8f30783115e3384721046258ce615b129c5 /ipc
parent8920d5ad6ba74ae8ab020e90cc4d976980e68701 (diff)
parentf01d1d546abb2f4028b5299092f529eefb01253a (diff)
Merge branch 'master' into next
Conflicts: fs/namei.c Manually merged per: diff --cc fs/namei.c index 734f2b5,bbc15c2..0000000 --- a/fs/namei.c +++ b/fs/namei.c @@@ -860,9 -848,8 +849,10 @@@ static int __link_path_walk(const char nd->flags |= LOOKUP_CONTINUE; err = exec_permission_lite(inode); if (err == -EAGAIN) - err = vfs_permission(nd, MAY_EXEC); + err = inode_permission(nd->path.dentry->d_inode, + MAY_EXEC); + if (!err) + err = ima_path_check(&nd->path, MAY_EXEC); if (err) break; @@@ -1525,14 -1506,9 +1509,14 @@@ int may_open(struct path *path, int acc flag &= ~O_TRUNC; } - error = vfs_permission(nd, acc_mode); + error = inode_permission(inode, acc_mode); if (error) return error; + - error = ima_path_check(&nd->path, ++ error = ima_path_check(path, + acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); + if (error) + return error; /* * An append-only file must be opened in append mode for writing. */ Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'ipc')
-rw-r--r--ipc/ipc_sysctl.c46
-rw-r--r--ipc/mqueue.c129
-rw-r--r--ipc/msg.c12
-rw-r--r--ipc/sem.c21
-rw-r--r--ipc/shm.c47
-rw-r--r--ipc/util.c18
6 files changed, 141 insertions, 132 deletions
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
index 0dfebc509426..4a7a12c95abe 100644
--- a/ipc/ipc_sysctl.c
+++ b/ipc/ipc_sysctl.c
@@ -26,29 +26,6 @@ static void *get_ipc(ctl_table *table)
26 return which; 26 return which;
27} 27}
28 28
29/*
30 * Routine that is called when the file "auto_msgmni" has successfully been
31 * written.
32 * Two values are allowed:
33 * 0: unregister msgmni's callback routine from the ipc namespace notifier
34 * chain. This means that msgmni won't be recomputed anymore upon memory
35 * add/remove or ipc namespace creation/removal.
36 * 1: register back the callback routine.
37 */
38static void ipc_auto_callback(int val)
39{
40 if (!val)
41 unregister_ipcns_notifier(current->nsproxy->ipc_ns);
42 else {
43 /*
44 * Re-enable automatic recomputing only if not already
45 * enabled.
46 */
47 recompute_msgmni(current->nsproxy->ipc_ns);
48 cond_register_ipcns_notifier(current->nsproxy->ipc_ns);
49 }
50}
51
52#ifdef CONFIG_PROC_FS 29#ifdef CONFIG_PROC_FS
53static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp, 30static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
54 void __user *buffer, size_t *lenp, loff_t *ppos) 31 void __user *buffer, size_t *lenp, loff_t *ppos)
@@ -94,6 +71,29 @@ static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
94 lenp, ppos); 71 lenp, ppos);
95} 72}
96 73
74/*
75 * Routine that is called when the file "auto_msgmni" has successfully been
76 * written.
77 * Two values are allowed:
78 * 0: unregister msgmni's callback routine from the ipc namespace notifier
79 * chain. This means that msgmni won't be recomputed anymore upon memory
80 * add/remove or ipc namespace creation/removal.
81 * 1: register back the callback routine.
82 */
83static void ipc_auto_callback(int val)
84{
85 if (!val)
86 unregister_ipcns_notifier(current->nsproxy->ipc_ns);
87 else {
88 /*
89 * Re-enable automatic recomputing only if not already
90 * enabled.
91 */
92 recompute_msgmni(current->nsproxy->ipc_ns);
93 cond_register_ipcns_notifier(current->nsproxy->ipc_ns);
94 }
95}
96
97static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, 97static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
98 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) 98 struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
99{ 99{
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index d9393f8e4c3e..54b4077fed79 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -120,7 +120,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
120 inode->i_mode = mode; 120 inode->i_mode = mode;
121 inode->i_uid = current_fsuid(); 121 inode->i_uid = current_fsuid();
122 inode->i_gid = current_fsgid(); 122 inode->i_gid = current_fsgid();
123 inode->i_blocks = 0;
124 inode->i_mtime = inode->i_ctime = inode->i_atime = 123 inode->i_mtime = inode->i_ctime = inode->i_atime =
125 CURRENT_TIME; 124 CURRENT_TIME;
126 125
@@ -506,7 +505,8 @@ static void __do_notify(struct mqueue_inode_info *info)
506 sig_i.si_errno = 0; 505 sig_i.si_errno = 0;
507 sig_i.si_code = SI_MESGQ; 506 sig_i.si_code = SI_MESGQ;
508 sig_i.si_value = info->notify.sigev_value; 507 sig_i.si_value = info->notify.sigev_value;
509 sig_i.si_pid = task_tgid_vnr(current); 508 sig_i.si_pid = task_tgid_nr_ns(current,
509 ns_of_pid(info->notify_owner));
510 sig_i.si_uid = current_uid(); 510 sig_i.si_uid = current_uid();
511 511
512 kill_pid_info(info->notify.sigev_signo, 512 kill_pid_info(info->notify.sigev_signo,
@@ -524,31 +524,27 @@ static void __do_notify(struct mqueue_inode_info *info)
524 wake_up(&info->wait_q); 524 wake_up(&info->wait_q);
525} 525}
526 526
527static long prepare_timeout(const struct timespec __user *u_arg) 527static long prepare_timeout(struct timespec *p)
528{ 528{
529 struct timespec ts, nowts; 529 struct timespec nowts;
530 long timeout; 530 long timeout;
531 531
532 if (u_arg) { 532 if (p) {
533 if (unlikely(copy_from_user(&ts, u_arg, 533 if (unlikely(p->tv_nsec < 0 || p->tv_sec < 0
534 sizeof(struct timespec)))) 534 || p->tv_nsec >= NSEC_PER_SEC))
535 return -EFAULT;
536
537 if (unlikely(ts.tv_nsec < 0 || ts.tv_sec < 0
538 || ts.tv_nsec >= NSEC_PER_SEC))
539 return -EINVAL; 535 return -EINVAL;
540 nowts = CURRENT_TIME; 536 nowts = CURRENT_TIME;
541 /* first subtract as jiffies can't be too big */ 537 /* first subtract as jiffies can't be too big */
542 ts.tv_sec -= nowts.tv_sec; 538 p->tv_sec -= nowts.tv_sec;
543 if (ts.tv_nsec < nowts.tv_nsec) { 539 if (p->tv_nsec < nowts.tv_nsec) {
544 ts.tv_nsec += NSEC_PER_SEC; 540 p->tv_nsec += NSEC_PER_SEC;
545 ts.tv_sec--; 541 p->tv_sec--;
546 } 542 }
547 ts.tv_nsec -= nowts.tv_nsec; 543 p->tv_nsec -= nowts.tv_nsec;
548 if (ts.tv_sec < 0) 544 if (p->tv_sec < 0)
549 return 0; 545 return 0;
550 546
551 timeout = timespec_to_jiffies(&ts) + 1; 547 timeout = timespec_to_jiffies(p) + 1;
552 } else 548 } else
553 return MAX_SCHEDULE_TIMEOUT; 549 return MAX_SCHEDULE_TIMEOUT;
554 550
@@ -592,22 +588,18 @@ static int mq_attr_ok(struct mq_attr *attr)
592 * Invoked when creating a new queue via sys_mq_open 588 * Invoked when creating a new queue via sys_mq_open
593 */ 589 */
594static struct file *do_create(struct dentry *dir, struct dentry *dentry, 590static struct file *do_create(struct dentry *dir, struct dentry *dentry,
595 int oflag, mode_t mode, struct mq_attr __user *u_attr) 591 int oflag, mode_t mode, struct mq_attr *attr)
596{ 592{
597 const struct cred *cred = current_cred(); 593 const struct cred *cred = current_cred();
598 struct mq_attr attr;
599 struct file *result; 594 struct file *result;
600 int ret; 595 int ret;
601 596
602 if (u_attr) { 597 if (attr) {
603 ret = -EFAULT;
604 if (copy_from_user(&attr, u_attr, sizeof(attr)))
605 goto out;
606 ret = -EINVAL; 598 ret = -EINVAL;
607 if (!mq_attr_ok(&attr)) 599 if (!mq_attr_ok(attr))
608 goto out; 600 goto out;
609 /* store for use during create */ 601 /* store for use during create */
610 dentry->d_fsdata = &attr; 602 dentry->d_fsdata = attr;
611 } 603 }
612 604
613 mode &= ~current->fs->umask; 605 mode &= ~current->fs->umask;
@@ -658,17 +650,19 @@ static struct file *do_open(struct dentry *dentry, int oflag)
658 return dentry_open(dentry, mqueue_mnt, oflag, cred); 650 return dentry_open(dentry, mqueue_mnt, oflag, cred);
659} 651}
660 652
661asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, 653SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
662 struct mq_attr __user *u_attr) 654 struct mq_attr __user *, u_attr)
663{ 655{
664 struct dentry *dentry; 656 struct dentry *dentry;
665 struct file *filp; 657 struct file *filp;
666 char *name; 658 char *name;
659 struct mq_attr attr;
667 int fd, error; 660 int fd, error;
668 661
669 error = audit_mq_open(oflag, mode, u_attr); 662 if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
670 if (error != 0) 663 return -EFAULT;
671 return error; 664
665 audit_mq_open(oflag, mode, u_attr ? &attr : NULL);
672 666
673 if (IS_ERR(name = getname(u_name))) 667 if (IS_ERR(name = getname(u_name)))
674 return PTR_ERR(name); 668 return PTR_ERR(name);
@@ -694,7 +688,8 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
694 filp = do_open(dentry, oflag); 688 filp = do_open(dentry, oflag);
695 } else { 689 } else {
696 filp = do_create(mqueue_mnt->mnt_root, dentry, 690 filp = do_create(mqueue_mnt->mnt_root, dentry,
697 oflag, mode, u_attr); 691 oflag, mode,
692 u_attr ? &attr : NULL);
698 } 693 }
699 } else { 694 } else {
700 error = -ENOENT; 695 error = -ENOENT;
@@ -726,7 +721,7 @@ out_putname:
726 return fd; 721 return fd;
727} 722}
728 723
729asmlinkage long sys_mq_unlink(const char __user *u_name) 724SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
730{ 725{
731 int err; 726 int err;
732 char *name; 727 char *name;
@@ -819,9 +814,9 @@ static inline void pipelined_receive(struct mqueue_inode_info *info)
819 sender->state = STATE_READY; 814 sender->state = STATE_READY;
820} 815}
821 816
822asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr, 817SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
823 size_t msg_len, unsigned int msg_prio, 818 size_t, msg_len, unsigned int, msg_prio,
824 const struct timespec __user *u_abs_timeout) 819 const struct timespec __user *, u_abs_timeout)
825{ 820{
826 struct file *filp; 821 struct file *filp;
827 struct inode *inode; 822 struct inode *inode;
@@ -829,17 +824,22 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
829 struct ext_wait_queue *receiver; 824 struct ext_wait_queue *receiver;
830 struct msg_msg *msg_ptr; 825 struct msg_msg *msg_ptr;
831 struct mqueue_inode_info *info; 826 struct mqueue_inode_info *info;
827 struct timespec ts, *p = NULL;
832 long timeout; 828 long timeout;
833 int ret; 829 int ret;
834 830
835 ret = audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout); 831 if (u_abs_timeout) {
836 if (ret != 0) 832 if (copy_from_user(&ts, u_abs_timeout,
837 return ret; 833 sizeof(struct timespec)))
834 return -EFAULT;
835 p = &ts;
836 }
838 837
839 if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX)) 838 if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
840 return -EINVAL; 839 return -EINVAL;
841 840
842 timeout = prepare_timeout(u_abs_timeout); 841 audit_mq_sendrecv(mqdes, msg_len, msg_prio, p);
842 timeout = prepare_timeout(p);
843 843
844 ret = -EBADF; 844 ret = -EBADF;
845 filp = fget(mqdes); 845 filp = fget(mqdes);
@@ -907,9 +907,9 @@ out:
907 return ret; 907 return ret;
908} 908}
909 909
910asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, 910SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
911 size_t msg_len, unsigned int __user *u_msg_prio, 911 size_t, msg_len, unsigned int __user *, u_msg_prio,
912 const struct timespec __user *u_abs_timeout) 912 const struct timespec __user *, u_abs_timeout)
913{ 913{
914 long timeout; 914 long timeout;
915 ssize_t ret; 915 ssize_t ret;
@@ -918,12 +918,17 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
918 struct inode *inode; 918 struct inode *inode;
919 struct mqueue_inode_info *info; 919 struct mqueue_inode_info *info;
920 struct ext_wait_queue wait; 920 struct ext_wait_queue wait;
921 struct timespec ts, *p = NULL;
921 922
922 ret = audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout); 923 if (u_abs_timeout) {
923 if (ret != 0) 924 if (copy_from_user(&ts, u_abs_timeout,
924 return ret; 925 sizeof(struct timespec)))
926 return -EFAULT;
927 p = &ts;
928 }
925 929
926 timeout = prepare_timeout(u_abs_timeout); 930 audit_mq_sendrecv(mqdes, msg_len, 0, p);
931 timeout = prepare_timeout(p);
927 932
928 ret = -EBADF; 933 ret = -EBADF;
929 filp = fget(mqdes); 934 filp = fget(mqdes);
@@ -992,8 +997,8 @@ out:
992 * and he isn't currently owner of notification, will be silently discarded. 997 * and he isn't currently owner of notification, will be silently discarded.
993 * It isn't explicitly defined in the POSIX. 998 * It isn't explicitly defined in the POSIX.
994 */ 999 */
995asmlinkage long sys_mq_notify(mqd_t mqdes, 1000SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
996 const struct sigevent __user *u_notification) 1001 const struct sigevent __user *, u_notification)
997{ 1002{
998 int ret; 1003 int ret;
999 struct file *filp; 1004 struct file *filp;
@@ -1003,17 +1008,17 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
1003 struct mqueue_inode_info *info; 1008 struct mqueue_inode_info *info;
1004 struct sk_buff *nc; 1009 struct sk_buff *nc;
1005 1010
1006 ret = audit_mq_notify(mqdes, u_notification); 1011 if (u_notification) {
1007 if (ret != 0)
1008 return ret;
1009
1010 nc = NULL;
1011 sock = NULL;
1012 if (u_notification != NULL) {
1013 if (copy_from_user(&notification, u_notification, 1012 if (copy_from_user(&notification, u_notification,
1014 sizeof(struct sigevent))) 1013 sizeof(struct sigevent)))
1015 return -EFAULT; 1014 return -EFAULT;
1015 }
1016 1016
1017 audit_mq_notify(mqdes, u_notification ? &notification : NULL);
1018
1019 nc = NULL;
1020 sock = NULL;
1021 if (u_notification != NULL) {
1017 if (unlikely(notification.sigev_notify != SIGEV_NONE && 1022 if (unlikely(notification.sigev_notify != SIGEV_NONE &&
1018 notification.sigev_notify != SIGEV_SIGNAL && 1023 notification.sigev_notify != SIGEV_SIGNAL &&
1019 notification.sigev_notify != SIGEV_THREAD)) 1024 notification.sigev_notify != SIGEV_THREAD))
@@ -1118,9 +1123,9 @@ out:
1118 return ret; 1123 return ret;
1119} 1124}
1120 1125
1121asmlinkage long sys_mq_getsetattr(mqd_t mqdes, 1126SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
1122 const struct mq_attr __user *u_mqstat, 1127 const struct mq_attr __user *, u_mqstat,
1123 struct mq_attr __user *u_omqstat) 1128 struct mq_attr __user *, u_omqstat)
1124{ 1129{
1125 int ret; 1130 int ret;
1126 struct mq_attr mqstat, omqstat; 1131 struct mq_attr mqstat, omqstat;
@@ -1150,11 +1155,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
1150 omqstat = info->attr; 1155 omqstat = info->attr;
1151 omqstat.mq_flags = filp->f_flags & O_NONBLOCK; 1156 omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
1152 if (u_mqstat) { 1157 if (u_mqstat) {
1153 ret = audit_mq_getsetattr(mqdes, &mqstat); 1158 audit_mq_getsetattr(mqdes, &mqstat);
1154 if (ret != 0) {
1155 spin_unlock(&info->lock);
1156 goto out_fput;
1157 }
1158 if (mqstat.mq_flags & O_NONBLOCK) 1159 if (mqstat.mq_flags & O_NONBLOCK)
1159 filp->f_flags |= O_NONBLOCK; 1160 filp->f_flags |= O_NONBLOCK;
1160 else 1161 else
diff --git a/ipc/msg.c b/ipc/msg.c
index b4eee1c6101d..2ceab7f12fcb 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -309,7 +309,7 @@ static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
309 return security_msg_queue_associate(msq, msgflg); 309 return security_msg_queue_associate(msq, msgflg);
310} 310}
311 311
312asmlinkage long sys_msgget(key_t key, int msgflg) 312SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg)
313{ 313{
314 struct ipc_namespace *ns; 314 struct ipc_namespace *ns;
315 struct ipc_ops msg_ops; 315 struct ipc_ops msg_ops;
@@ -466,7 +466,7 @@ out_up:
466 return err; 466 return err;
467} 467}
468 468
469asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) 469SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
470{ 470{
471 struct msg_queue *msq; 471 struct msg_queue *msq;
472 int err, version; 472 int err, version;
@@ -723,8 +723,8 @@ out_free:
723 return err; 723 return err;
724} 724}
725 725
726asmlinkage long 726SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
727sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) 727 int, msgflg)
728{ 728{
729 long mtype; 729 long mtype;
730 730
@@ -904,8 +904,8 @@ out_unlock:
904 return msgsz; 904 return msgsz;
905} 905}
906 906
907asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, 907SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
908 long msgtyp, int msgflg) 908 long, msgtyp, int, msgflg)
909{ 909{
910 long err, mtype; 910 long err, mtype;
911 911
diff --git a/ipc/sem.c b/ipc/sem.c
index 082122469b17..16a2189e96f9 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -58,7 +58,7 @@
58 * SMP-threaded, sysctl's added 58 * SMP-threaded, sysctl's added
59 * (c) 1999 Manfred Spraul <manfred@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
62 * Lockless wakeup 62 * Lockless wakeup
63 * (c) 2003 Manfred Spraul <manfred@colorfullife.com> 63 * (c) 2003 Manfred Spraul <manfred@colorfullife.com>
64 * 64 *
@@ -308,7 +308,7 @@ static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
308 return 0; 308 return 0;
309} 309}
310 310
311asmlinkage long sys_semget(key_t key, int nsems, int semflg) 311SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg)
312{ 312{
313 struct ipc_namespace *ns; 313 struct ipc_namespace *ns;
314 struct ipc_ops sem_ops; 314 struct ipc_ops sem_ops;
@@ -887,7 +887,7 @@ out_up:
887 return err; 887 return err;
888} 888}
889 889
890asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) 890SYSCALL_DEFINE(semctl)(int semid, int semnum, int cmd, union semun arg)
891{ 891{
892 int err = -EINVAL; 892 int err = -EINVAL;
893 int version; 893 int version;
@@ -923,6 +923,13 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
923 return -EINVAL; 923 return -EINVAL;
924 } 924 }
925} 925}
926#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
927asmlinkage long SyS_semctl(int semid, int semnum, int cmd, union semun arg)
928{
929 return SYSC_semctl((int) semid, (int) semnum, (int) cmd, arg);
930}
931SYSCALL_ALIAS(sys_semctl, SyS_semctl);
932#endif
926 933
927/* If the task doesn't already have a undo_list, then allocate one 934/* If the task doesn't already have a undo_list, then allocate one
928 * here. We guarantee there is only one thread using this undo list, 935 * here. We guarantee there is only one thread using this undo list,
@@ -1048,8 +1055,8 @@ out:
1048 return un; 1055 return un;
1049} 1056}
1050 1057
1051asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops, 1058SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
1052 unsigned nsops, const struct timespec __user *timeout) 1059 unsigned, nsops, const struct timespec __user *, timeout)
1053{ 1060{
1054 int error = -EINVAL; 1061 int error = -EINVAL;
1055 struct sem_array *sma; 1062 struct sem_array *sma;
@@ -1216,7 +1223,6 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops,
1216 if (timeout && jiffies_left == 0) 1223 if (timeout && jiffies_left == 0)
1217 error = -EAGAIN; 1224 error = -EAGAIN;
1218 list_del(&queue.list); 1225 list_del(&queue.list);
1219 goto out_unlock_free;
1220 1226
1221out_unlock_free: 1227out_unlock_free:
1222 sem_unlock(sma); 1228 sem_unlock(sma);
@@ -1226,7 +1232,8 @@ out_free:
1226 return error; 1232 return error;
1227} 1233}
1228 1234
1229asmlinkage long sys_semop (int semid, struct sembuf __user *tsops, unsigned nsops) 1235SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops,
1236 unsigned, nsops)
1230{ 1237{
1231 return sys_semtimedop(semid, tsops, nsops, NULL); 1238 return sys_semtimedop(semid, tsops, nsops, NULL);
1232} 1239}
diff --git a/ipc/shm.c b/ipc/shm.c
index d39bd7637b1c..2bd4809508a4 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -76,7 +76,7 @@ void shm_init_ns(struct ipc_namespace *ns)
76 ns->shm_ctlall = SHMALL; 76 ns->shm_ctlall = SHMALL;
77 ns->shm_ctlmni = SHMMNI; 77 ns->shm_ctlmni = SHMMNI;
78 ns->shm_tot = 0; 78 ns->shm_tot = 0;
79 ipc_init_ids(&ns->ids[IPC_SHM_IDS]); 79 ipc_init_ids(&shm_ids(ns));
80} 80}
81 81
82/* 82/*
@@ -369,14 +369,14 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
369 file = hugetlb_file_setup(name, size); 369 file = hugetlb_file_setup(name, size);
370 shp->mlock_user = current_user(); 370 shp->mlock_user = current_user();
371 } else { 371 } else {
372 int acctflag = VM_ACCOUNT; 372 int acctflag = 0;
373 /* 373 /*
374 * Do not allow no accounting for OVERCOMMIT_NEVER, even 374 * Do not allow no accounting for OVERCOMMIT_NEVER, even
375 * if it's asked for. 375 * if it's asked for.
376 */ 376 */
377 if ((shmflg & SHM_NORESERVE) && 377 if ((shmflg & SHM_NORESERVE) &&
378 sysctl_overcommit_memory != OVERCOMMIT_NEVER) 378 sysctl_overcommit_memory != OVERCOMMIT_NEVER)
379 acctflag = 0; 379 acctflag = VM_NORESERVE;
380 file = shmem_file_setup(name, size, acctflag); 380 file = shmem_file_setup(name, size, acctflag);
381 } 381 }
382 error = PTR_ERR(file); 382 error = PTR_ERR(file);
@@ -442,7 +442,7 @@ static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
442 return 0; 442 return 0;
443} 443}
444 444
445asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) 445SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg)
446{ 446{
447 struct ipc_namespace *ns; 447 struct ipc_namespace *ns;
448 struct ipc_ops shm_ops; 448 struct ipc_ops shm_ops;
@@ -567,11 +567,15 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
567 struct hstate *h = hstate_file(shp->shm_file); 567 struct hstate *h = hstate_file(shp->shm_file);
568 *rss += pages_per_huge_page(h) * mapping->nrpages; 568 *rss += pages_per_huge_page(h) * mapping->nrpages;
569 } else { 569 } else {
570#ifdef CONFIG_SHMEM
570 struct shmem_inode_info *info = SHMEM_I(inode); 571 struct shmem_inode_info *info = SHMEM_I(inode);
571 spin_lock(&info->lock); 572 spin_lock(&info->lock);
572 *rss += inode->i_mapping->nrpages; 573 *rss += inode->i_mapping->nrpages;
573 *swp += info->swapped; 574 *swp += info->swapped;
574 spin_unlock(&info->lock); 575 spin_unlock(&info->lock);
576#else
577 *rss += inode->i_mapping->nrpages;
578#endif
575 } 579 }
576 580
577 total++; 581 total++;
@@ -623,7 +627,7 @@ out_up:
623 return err; 627 return err;
624} 628}
625 629
626asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) 630SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
627{ 631{
628 struct shmid_kernel *shp; 632 struct shmid_kernel *shp;
629 int err, version; 633 int err, version;
@@ -646,7 +650,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
646 if (err) 650 if (err)
647 return err; 651 return err;
648 652
649 memset(&shminfo,0,sizeof(shminfo)); 653 memset(&shminfo, 0, sizeof(shminfo));
650 shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni; 654 shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
651 shminfo.shmmax = ns->shm_ctlmax; 655 shminfo.shmmax = ns->shm_ctlmax;
652 shminfo.shmall = ns->shm_ctlall; 656 shminfo.shmall = ns->shm_ctlall;
@@ -671,7 +675,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
671 if (err) 675 if (err)
672 return err; 676 return err;
673 677
674 memset(&shm_info,0,sizeof(shm_info)); 678 memset(&shm_info, 0, sizeof(shm_info));
675 down_read(&shm_ids(ns).rw_mutex); 679 down_read(&shm_ids(ns).rw_mutex);
676 shm_info.used_ids = shm_ids(ns).in_use; 680 shm_info.used_ids = shm_ids(ns).in_use;
677 shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp); 681 shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
@@ -680,7 +684,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
680 shm_info.swap_successes = 0; 684 shm_info.swap_successes = 0;
681 err = ipc_get_maxid(&shm_ids(ns)); 685 err = ipc_get_maxid(&shm_ids(ns));
682 up_read(&shm_ids(ns).rw_mutex); 686 up_read(&shm_ids(ns).rw_mutex);
683 if(copy_to_user (buf, &shm_info, sizeof(shm_info))) { 687 if (copy_to_user(buf, &shm_info, sizeof(shm_info))) {
684 err = -EFAULT; 688 err = -EFAULT;
685 goto out; 689 goto out;
686 } 690 }
@@ -694,11 +698,6 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
694 struct shmid64_ds tbuf; 698 struct shmid64_ds tbuf;
695 int result; 699 int result;
696 700
697 if (!buf) {
698 err = -EFAULT;
699 goto out;
700 }
701
702 if (cmd == SHM_STAT) { 701 if (cmd == SHM_STAT) {
703 shp = shm_lock(ns, shmid); 702 shp = shm_lock(ns, shmid);
704 if (IS_ERR(shp)) { 703 if (IS_ERR(shp)) {
@@ -714,7 +713,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
714 } 713 }
715 result = 0; 714 result = 0;
716 } 715 }
717 err=-EACCES; 716 err = -EACCES;
718 if (ipcperms (&shp->shm_perm, S_IRUGO)) 717 if (ipcperms (&shp->shm_perm, S_IRUGO))
719 goto out_unlock; 718 goto out_unlock;
720 err = security_shm_shmctl(shp, cmd); 719 err = security_shm_shmctl(shp, cmd);
@@ -749,9 +748,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
749 goto out; 748 goto out;
750 } 749 }
751 750
752 err = audit_ipc_obj(&(shp->shm_perm)); 751 audit_ipc_obj(&(shp->shm_perm));
753 if (err)
754 goto out_unlock;
755 752
756 if (!capable(CAP_IPC_LOCK)) { 753 if (!capable(CAP_IPC_LOCK)) {
757 uid_t euid = current_euid(); 754 uid_t euid = current_euid();
@@ -949,7 +946,7 @@ out_put_dentry:
949 goto out_nattch; 946 goto out_nattch;
950} 947}
951 948
952asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg) 949SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
953{ 950{
954 unsigned long ret; 951 unsigned long ret;
955 long err; 952 long err;
@@ -965,7 +962,7 @@ asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg)
965 * detach and kill segment if marked destroyed. 962 * detach and kill segment if marked destroyed.
966 * The work is done in shm_close. 963 * The work is done in shm_close.
967 */ 964 */
968asmlinkage long sys_shmdt(char __user *shmaddr) 965SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
969{ 966{
970 struct mm_struct *mm = current->mm; 967 struct mm_struct *mm = current->mm;
971 struct vm_area_struct *vma, *next; 968 struct vm_area_struct *vma, *next;
@@ -1000,6 +997,7 @@ asmlinkage long sys_shmdt(char __user *shmaddr)
1000 */ 997 */
1001 vma = find_vma(mm, addr); 998 vma = find_vma(mm, addr);
1002 999
1000#ifdef CONFIG_MMU
1003 while (vma) { 1001 while (vma) {
1004 next = vma->vm_next; 1002 next = vma->vm_next;
1005 1003
@@ -1044,6 +1042,17 @@ asmlinkage long sys_shmdt(char __user *shmaddr)
1044 vma = next; 1042 vma = next;
1045 } 1043 }
1046 1044
1045#else /* CONFIG_MMU */
1046 /* under NOMMU conditions, the exact address to be destroyed must be
1047 * given */
1048 retval = -EINVAL;
1049 if (vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) {
1050 do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start);
1051 retval = 0;
1052 }
1053
1054#endif
1055
1047 up_write(&mm->mmap_sem); 1056 up_write(&mm->mmap_sem);
1048 return retval; 1057 return retval;
1049} 1058}
diff --git a/ipc/util.c b/ipc/util.c
index 5a1808c774a2..7585a72e259b 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -624,10 +624,9 @@ void ipc_rcu_putref(void *ptr)
624int ipcperms (struct kern_ipc_perm *ipcp, short flag) 624int ipcperms (struct kern_ipc_perm *ipcp, short flag)
625{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ 625{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
626 uid_t euid = current_euid(); 626 uid_t euid = current_euid();
627 int requested_mode, granted_mode, err; 627 int requested_mode, granted_mode;
628 628
629 if (unlikely((err = audit_ipc_obj(ipcp)))) 629 audit_ipc_obj(ipcp);
630 return err;
631 requested_mode = (flag >> 6) | (flag >> 3) | flag; 630 requested_mode = (flag >> 6) | (flag >> 3) | flag;
632 granted_mode = ipcp->mode; 631 granted_mode = ipcp->mode;
633 if (euid == ipcp->cuid || 632 if (euid == ipcp->cuid ||
@@ -803,16 +802,10 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
803 goto out_up; 802 goto out_up;
804 } 803 }
805 804
806 err = audit_ipc_obj(ipcp); 805 audit_ipc_obj(ipcp);
807 if (err) 806 if (cmd == IPC_SET)
808 goto out_unlock; 807 audit_ipc_set_perm(extra_perm, perm->uid,
809
810 if (cmd == IPC_SET) {
811 err = audit_ipc_set_perm(extra_perm, perm->uid,
812 perm->gid, perm->mode); 808 perm->gid, perm->mode);
813 if (err)
814 goto out_unlock;
815 }
816 809
817 euid = current_euid(); 810 euid = current_euid();
818 if (euid == ipcp->cuid || 811 if (euid == ipcp->cuid ||
@@ -820,7 +813,6 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
820 return ipcp; 813 return ipcp;
821 814
822 err = -EPERM; 815 err = -EPERM;
823out_unlock:
824 ipc_unlock(ipcp); 816 ipc_unlock(ipcp);
825out_up: 817out_up:
826 up_write(&ids->rw_mutex); 818 up_write(&ids->rw_mutex);