aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/shm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/shm.c')
-rw-r--r--ipc/shm.c47
1 files changed, 28 insertions, 19 deletions
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}