diff options
Diffstat (limited to 'ipc/shm.c')
-rw-r--r-- | ipc/shm.c | 47 |
1 files changed, 28 insertions, 19 deletions
@@ -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 | ||
445 | asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) | 445 | SYSCALL_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 | ||
626 | asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) | 630 | SYSCALL_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 | ||
952 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg) | 949 | SYSCALL_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 | */ |
968 | asmlinkage long sys_shmdt(char __user *shmaddr) | 965 | SYSCALL_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 | } |