diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-18 12:37:14 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-18 12:37:14 -0500 |
commit | b2b062b8163391c42b3219d466ca1ac9742b9c7b (patch) | |
tree | f3f920c09b8de694b1bc1d4b878cfd2b0b98c913 /ipc | |
parent | a9de18eb761f7c1c860964b2e5addc1a35c7e861 (diff) | |
parent | 99937d6455cea95405ac681c86a857d0fcd530bd (diff) |
Merge branch 'core/percpu' into stackprotector
Conflicts:
arch/x86/include/asm/pda.h
arch/x86/include/asm/system.h
Also, moved include/asm-x86/stackprotector.h to arch/x86/include/asm.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc_sysctl.c | 46 | ||||
-rw-r--r-- | ipc/mqueue.c | 101 | ||||
-rw-r--r-- | ipc/sem.c | 3 | ||||
-rw-r--r-- | ipc/shm.c | 31 | ||||
-rw-r--r-- | ipc/util.c | 18 |
5 files changed, 98 insertions, 101 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 | */ | ||
38 | static 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 |
53 | static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp, | 30 | static 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 | */ | ||
83 | static 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 | |||
97 | static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, | 97 | static 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..23fdb8492b8e 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 | ||
527 | static long prepare_timeout(const struct timespec __user *u_arg) | 527 | static 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 | */ |
594 | static struct file *do_create(struct dentry *dir, struct dentry *dentry, | 590 | static 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; |
@@ -664,11 +656,13 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, | |||
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; |
@@ -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); |
@@ -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); |
@@ -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(¬ification, u_notification, | 1012 | if (copy_from_user(¬ification, 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 ? ¬ification : 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)) |
@@ -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 |
@@ -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 | * |
@@ -1216,7 +1216,6 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops, | |||
1216 | if (timeout && jiffies_left == 0) | 1216 | if (timeout && jiffies_left == 0) |
1217 | error = -EAGAIN; | 1217 | error = -EAGAIN; |
1218 | list_del(&queue.list); | 1218 | list_del(&queue.list); |
1219 | goto out_unlock_free; | ||
1220 | 1219 | ||
1221 | out_unlock_free: | 1220 | out_unlock_free: |
1222 | sem_unlock(sma); | 1221 | sem_unlock(sma); |
@@ -75,7 +75,7 @@ void shm_init_ns(struct ipc_namespace *ns) | |||
75 | ns->shm_ctlall = SHMALL; | 75 | ns->shm_ctlall = SHMALL; |
76 | ns->shm_ctlmni = SHMMNI; | 76 | ns->shm_ctlmni = SHMMNI; |
77 | ns->shm_tot = 0; | 77 | ns->shm_tot = 0; |
78 | ipc_init_ids(&ns->ids[IPC_SHM_IDS]); | 78 | ipc_init_ids(&shm_ids(ns)); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* | 81 | /* |
@@ -644,7 +644,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | |||
644 | if (err) | 644 | if (err) |
645 | return err; | 645 | return err; |
646 | 646 | ||
647 | memset(&shminfo,0,sizeof(shminfo)); | 647 | memset(&shminfo, 0, sizeof(shminfo)); |
648 | shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni; | 648 | shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni; |
649 | shminfo.shmmax = ns->shm_ctlmax; | 649 | shminfo.shmmax = ns->shm_ctlmax; |
650 | shminfo.shmall = ns->shm_ctlall; | 650 | shminfo.shmall = ns->shm_ctlall; |
@@ -669,7 +669,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | |||
669 | if (err) | 669 | if (err) |
670 | return err; | 670 | return err; |
671 | 671 | ||
672 | memset(&shm_info,0,sizeof(shm_info)); | 672 | memset(&shm_info, 0, sizeof(shm_info)); |
673 | down_read(&shm_ids(ns).rw_mutex); | 673 | down_read(&shm_ids(ns).rw_mutex); |
674 | shm_info.used_ids = shm_ids(ns).in_use; | 674 | shm_info.used_ids = shm_ids(ns).in_use; |
675 | shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp); | 675 | shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp); |
@@ -678,7 +678,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | |||
678 | shm_info.swap_successes = 0; | 678 | shm_info.swap_successes = 0; |
679 | err = ipc_get_maxid(&shm_ids(ns)); | 679 | err = ipc_get_maxid(&shm_ids(ns)); |
680 | up_read(&shm_ids(ns).rw_mutex); | 680 | up_read(&shm_ids(ns).rw_mutex); |
681 | if(copy_to_user (buf, &shm_info, sizeof(shm_info))) { | 681 | if (copy_to_user(buf, &shm_info, sizeof(shm_info))) { |
682 | err = -EFAULT; | 682 | err = -EFAULT; |
683 | goto out; | 683 | goto out; |
684 | } | 684 | } |
@@ -692,11 +692,6 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | |||
692 | struct shmid64_ds tbuf; | 692 | struct shmid64_ds tbuf; |
693 | int result; | 693 | int result; |
694 | 694 | ||
695 | if (!buf) { | ||
696 | err = -EFAULT; | ||
697 | goto out; | ||
698 | } | ||
699 | |||
700 | if (cmd == SHM_STAT) { | 695 | if (cmd == SHM_STAT) { |
701 | shp = shm_lock(ns, shmid); | 696 | shp = shm_lock(ns, shmid); |
702 | if (IS_ERR(shp)) { | 697 | if (IS_ERR(shp)) { |
@@ -712,7 +707,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | |||
712 | } | 707 | } |
713 | result = 0; | 708 | result = 0; |
714 | } | 709 | } |
715 | err=-EACCES; | 710 | err = -EACCES; |
716 | if (ipcperms (&shp->shm_perm, S_IRUGO)) | 711 | if (ipcperms (&shp->shm_perm, S_IRUGO)) |
717 | goto out_unlock; | 712 | goto out_unlock; |
718 | err = security_shm_shmctl(shp, cmd); | 713 | err = security_shm_shmctl(shp, cmd); |
@@ -747,9 +742,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | |||
747 | goto out; | 742 | goto out; |
748 | } | 743 | } |
749 | 744 | ||
750 | err = audit_ipc_obj(&(shp->shm_perm)); | 745 | audit_ipc_obj(&(shp->shm_perm)); |
751 | if (err) | ||
752 | goto out_unlock; | ||
753 | 746 | ||
754 | if (!capable(CAP_IPC_LOCK)) { | 747 | if (!capable(CAP_IPC_LOCK)) { |
755 | uid_t euid = current_euid(); | 748 | uid_t euid = current_euid(); |
@@ -997,6 +990,7 @@ asmlinkage long sys_shmdt(char __user *shmaddr) | |||
997 | */ | 990 | */ |
998 | vma = find_vma(mm, addr); | 991 | vma = find_vma(mm, addr); |
999 | 992 | ||
993 | #ifdef CONFIG_MMU | ||
1000 | while (vma) { | 994 | while (vma) { |
1001 | next = vma->vm_next; | 995 | next = vma->vm_next; |
1002 | 996 | ||
@@ -1041,6 +1035,17 @@ asmlinkage long sys_shmdt(char __user *shmaddr) | |||
1041 | vma = next; | 1035 | vma = next; |
1042 | } | 1036 | } |
1043 | 1037 | ||
1038 | #else /* CONFIG_MMU */ | ||
1039 | /* under NOMMU conditions, the exact address to be destroyed must be | ||
1040 | * given */ | ||
1041 | retval = -EINVAL; | ||
1042 | if (vma->vm_start == addr && vma->vm_ops == &shm_vm_ops) { | ||
1043 | do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start); | ||
1044 | retval = 0; | ||
1045 | } | ||
1046 | |||
1047 | #endif | ||
1048 | |||
1044 | up_write(&mm->mmap_sem); | 1049 | up_write(&mm->mmap_sem); |
1045 | return retval; | 1050 | return retval; |
1046 | } | 1051 | } |
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) | |||
624 | int ipcperms (struct kern_ipc_perm *ipcp, short flag) | 624 | int 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; |
823 | out_unlock: | ||
824 | ipc_unlock(ipcp); | 816 | ipc_unlock(ipcp); |
825 | out_up: | 817 | out_up: |
826 | up_write(&ids->rw_mutex); | 818 | up_write(&ids->rw_mutex); |