]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/sysv_shm.c
xnu-2422.115.4.tar.gz
[apple/xnu.git] / bsd / kern / sysv_shm.c
index 4a93dc597eb20212b912f336eb6e0e985764d6c3..caed4c433c277da2bf3a9e2efe4b484e02215af2 100644 (file)
@@ -585,10 +585,20 @@ shmctl(__unused struct proc *p, struct shmctl_args *uap, int32_t *retval)
                }
 
                if (IS_64BIT_PROCESS(p)) {
-                       error = copyout((caddr_t)&shmseg->u, uap->buf, sizeof(struct user_shmid_ds));
+                       struct user_shmid_ds shmid_ds;
+                       memcpy(&shmid_ds, &shmseg->u, sizeof(struct user_shmid_ds));
+                       
+                       /* Clear kernel reserved pointer before copying to user space */
+                       shmid_ds.shm_internal = USER_ADDR_NULL;
+                       
+                       error = copyout(&shmid_ds, uap->buf, sizeof(shmid_ds));
                } else {
                        struct user32_shmid_ds shmid_ds32;
                        shmid_ds_64to32(&shmseg->u, &shmid_ds32);
+                       
+                       /* Clear kernel reserved pointer before copying to user space */
+                       shmid_ds32.shm_internal = (user32_addr_t)0;
+                       
                        error = copyout(&shmid_ds32, uap->buf, sizeof(shmid_ds32));
                }
                if (error) {
@@ -774,7 +784,7 @@ shmget_allocate_segment(struct proc *p, struct shmget_args *uap, int mode,
        shmid = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
 
        shmseg->u.shm_perm.cuid = shmseg->u.shm_perm.uid = kauth_cred_getuid(cred);
-       shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = cred->cr_gid;
+       shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = kauth_cred_getgid(cred);
        shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode & SHMSEG_WANTED) |
            (mode & ACCESSPERMS) | SHMSEG_ALLOCATED;
        shmseg->u.shm_segsz = uap->size;
@@ -1071,6 +1081,7 @@ IPCS_shm_sysctl(__unused struct sysctl_oid *oidp, __unused void *arg1,
                struct user_IPCS_command u64;
        } ipcs;
        struct user32_shmid_ds shmid_ds32;      /* post conversion, 32 bit version */
+       struct user_shmid_ds   shmid_ds;        /* 64 bit version */
        void *shmid_dsp;
        size_t ipcs_sz = sizeof(struct user_IPCS_command);
        size_t shmid_ds_sz = sizeof(struct user_shmid_ds);
@@ -1142,7 +1153,18 @@ IPCS_shm_sysctl(__unused struct sysctl_oid *oidp, __unused void *arg1,
                 */
                if (!IS_64BIT_PROCESS(p)) {
                        shmid_ds_64to32(shmid_dsp, &shmid_ds32);
+                       
+                       /* Clear kernel reserved pointer before copying to user space */
+                       shmid_ds32.shm_internal = (user32_addr_t)0;
+                       
                        shmid_dsp = &shmid_ds32;
+               } else {
+                       memcpy(&shmid_ds, shmid_dsp, sizeof(shmid_ds));
+
+                       /* Clear kernel reserved pointer before copying to user space */
+                       shmid_ds.shm_internal = USER_ADDR_NULL;
+                       
+                       shmid_dsp = &shmid_ds;
                }
                error = copyout(shmid_dsp, ipcs.u64.ipcs_data, ipcs.u64.ipcs_datalen);
                if (!error) {
@@ -1165,26 +1187,26 @@ ipcs_shm_sysctl_out:
        return(error);
 }
 
-SYSCTL_NODE(_kern, KERN_SYSV, sysv, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "SYSV");
+SYSCTL_NODE(_kern, KERN_SYSV, sysv, CTLFLAG_RW | CTLFLAG_LOCKED | CTLFLAG_ANYBODY, 0, "SYSV");
 
-SYSCTL_PROC(_kern_sysv, OID_AUTO, shmmax, CTLTYPE_QUAD | CTLFLAG_RW,
+SYSCTL_PROC(_kern_sysv, OID_AUTO, shmmax, CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
     &shminfo.shmmax, 0, &sysctl_shminfo ,"Q","shmmax");
 
-SYSCTL_PROC(_kern_sysv, OID_AUTO, shmmin, CTLTYPE_QUAD | CTLFLAG_RW,
+SYSCTL_PROC(_kern_sysv, OID_AUTO, shmmin, CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
     &shminfo.shmmin, 0, &sysctl_shminfo ,"Q","shmmin");
 
-SYSCTL_PROC(_kern_sysv, OID_AUTO, shmmni, CTLTYPE_QUAD | CTLFLAG_RW,
+SYSCTL_PROC(_kern_sysv, OID_AUTO, shmmni, CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
     &shminfo.shmmni, 0, &sysctl_shminfo ,"Q","shmmni");
 
-SYSCTL_PROC(_kern_sysv, OID_AUTO, shmseg, CTLTYPE_QUAD | CTLFLAG_RW,
+SYSCTL_PROC(_kern_sysv, OID_AUTO, shmseg, CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
     &shminfo.shmseg, 0, &sysctl_shminfo ,"Q","shmseg");
 
-SYSCTL_PROC(_kern_sysv, OID_AUTO, shmall, CTLTYPE_QUAD | CTLFLAG_RW,
+SYSCTL_PROC(_kern_sysv, OID_AUTO, shmall, CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
     &shminfo.shmall, 0, &sysctl_shminfo ,"Q","shmall");
 
-SYSCTL_NODE(_kern_sysv, OID_AUTO, ipcs, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "SYSVIPCS");
+SYSCTL_NODE(_kern_sysv, OID_AUTO, ipcs, CTLFLAG_RW | CTLFLAG_LOCKED | CTLFLAG_ANYBODY, 0, "SYSVIPCS");
 
-SYSCTL_PROC(_kern_sysv_ipcs, OID_AUTO, shm, CTLFLAG_RW|CTLFLAG_ANYBODY,
+SYSCTL_PROC(_kern_sysv_ipcs, OID_AUTO, shm, CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED,
        0, 0, IPCS_shm_sysctl,
        "S,IPCS_shm_command",
        "ipcs shm command interface");