aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipc/shm.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index 22cffd78dbb1..3e123987f054 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -820,29 +820,24 @@ out_up:
820 return err; 820 return err;
821} 821}
822 822
823SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) 823static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
824 int cmd, int version, void __user *buf)
824{ 825{
826 int err;
825 struct shmid_kernel *shp; 827 struct shmid_kernel *shp;
826 int err, version;
827 struct ipc_namespace *ns;
828 828
829 if (cmd < 0 || shmid < 0) { 829 /* preliminary security checks for *_INFO */
830 err = -EINVAL; 830 if (cmd == IPC_INFO || cmd == SHM_INFO) {
831 goto out; 831 err = security_shm_shmctl(NULL, cmd);
832 if (err)
833 return err;
832 } 834 }
833 835
834 version = ipc_parse_version(&cmd); 836 switch (cmd) {
835 ns = current->nsproxy->ipc_ns;
836
837 switch (cmd) { /* replace with proc interface ? */
838 case IPC_INFO: 837 case IPC_INFO:
839 { 838 {
840 struct shminfo64 shminfo; 839 struct shminfo64 shminfo;
841 840
842 err = security_shm_shmctl(NULL, cmd);
843 if (err)
844 return err;
845
846 memset(&shminfo, 0, sizeof(shminfo)); 841 memset(&shminfo, 0, sizeof(shminfo));
847 shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni; 842 shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
848 shminfo.shmmax = ns->shm_ctlmax; 843 shminfo.shmmax = ns->shm_ctlmax;
@@ -864,10 +859,6 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
864 { 859 {
865 struct shm_info shm_info; 860 struct shm_info shm_info;
866 861
867 err = security_shm_shmctl(NULL, cmd);
868 if (err)
869 return err;
870
871 memset(&shm_info, 0, sizeof(shm_info)); 862 memset(&shm_info, 0, sizeof(shm_info));
872 down_read(&shm_ids(ns).rw_mutex); 863 down_read(&shm_ids(ns).rw_mutex);
873 shm_info.used_ids = shm_ids(ns).in_use; 864 shm_info.used_ids = shm_ids(ns).in_use;
@@ -928,6 +919,36 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
928 err = result; 919 err = result;
929 goto out; 920 goto out;
930 } 921 }
922 default:
923 return -EINVAL;
924 }
925
926out_unlock:
927 shm_unlock(shp);
928out:
929 return err;
930}
931
932SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
933{
934 struct shmid_kernel *shp;
935 int err, version;
936 struct ipc_namespace *ns;
937
938 if (cmd < 0 || shmid < 0) {
939 err = -EINVAL;
940 goto out;
941 }
942
943 version = ipc_parse_version(&cmd);
944 ns = current->nsproxy->ipc_ns;
945
946 switch (cmd) {
947 case IPC_INFO:
948 case SHM_INFO:
949 case SHM_STAT:
950 case IPC_STAT:
951 return shmctl_nolock(ns, shmid, cmd, version, buf);
931 case SHM_LOCK: 952 case SHM_LOCK:
932 case SHM_UNLOCK: 953 case SHM_UNLOCK:
933 { 954 {