]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/posix_sem.c
xnu-2422.90.20.tar.gz
[apple/xnu.git] / bsd / kern / posix_sem.c
index a2cd627f1c6fd0114179f3f8270ce0b4f661274f..18f5d4b738848beee6d1b7b046378fa7b967a1e9 100644 (file)
@@ -30,7 +30,7 @@
  *     All Rights Reserved.
  */
 /*
- * posix_shm.c : Support for POSIX semaphore APIs
+ * posix_sem.c : Support for POSIX semaphore APIs
  *
  *     File:   posix_sem.c
  *     Author: Ananthakrishna Ramesh
@@ -85,7 +85,7 @@
 
 
 #define f_flag f_fglob->fg_flag
-#define f_type f_fglob->fg_type
+#define f_type f_fglob->fg_ops->fo_type
 #define f_msgcount f_fglob->fg_msgcount
 #define f_cred f_fglob->fg_cred
 #define f_ops f_fglob->fg_ops
@@ -101,8 +101,9 @@ struct pseminfo {
        gid_t           psem_gid;
        char            psem_name[PSEMNAMLEN + 1];      /* segment name */
        semaphore_t     psem_semobject;
-       proc_t          sem_proc;
        struct label *  psem_label;
+       pid_t           psem_creator_pid;
+       uint64_t        psem_creator_uniqueid;
 };
 #define PSEMINFO_NULL (struct pseminfo *)0
 
@@ -155,9 +156,9 @@ u_long      psemhash;                               /* size of hash table - 1 */
 long   psemnument;                     /* number of cache entries allocated */
 long   posix_sem_max = 10000;          /* tunable for max POSIX semaphores */
                                        /* 10000 limits to ~1M of memory */
-SYSCTL_NODE(_kern, KERN_POSIX, posix, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Posix");
-SYSCTL_NODE(_kern_posix, OID_AUTO, sem, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Semaphores");
-SYSCTL_LONG (_kern_posix_sem, OID_AUTO, max, CTLFLAG_RW, &posix_sem_max, "max");
+SYSCTL_NODE(_kern, KERN_POSIX, posix, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "Posix");
+SYSCTL_NODE(_kern_posix, OID_AUTO, sem, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "Semaphores");
+SYSCTL_LONG (_kern_posix_sem, OID_AUTO, max, CTLFLAG_RW | CTLFLAG_LOCKED, &posix_sem_max, "max");
 
 struct psemstats psemstats;            /* cache effectiveness statistics */
 
@@ -177,9 +178,16 @@ static int psem_closefile (struct fileglob *fp, vfs_context_t ctx);
 
 static int psem_kqfilter (struct fileproc *fp, struct knote *kn, vfs_context_t ctx);
 
-struct         fileops psemops =
-       { psem_read, psem_write, psem_ioctl, psem_select, psem_closefile, psem_kqfilter, NULL };
-
+static const struct fileops psemops = {
+       DTYPE_PSXSEM,
+       psem_read,
+       psem_write,
+       psem_ioctl,
+       psem_select,
+       psem_closefile,
+       psem_kqfilter,
+       NULL
+};
 
 static lck_grp_t       *psx_sem_subsys_lck_grp;
 static lck_grp_attr_t  *psx_sem_subsys_lck_grp_attr;
@@ -524,13 +532,14 @@ sem_open(proc_t p, struct sem_open_args *uap, user_addr_t *retval)
                pinfo->psem_flags = PSEM_DEFINED | PSEM_INCREATE;
                pinfo->psem_usecount = 1;
                pinfo->psem_mode = cmode;
-               pinfo->psem_uid = kauth_cred_getuid(kauth_cred_get());
-               pinfo->psem_gid = kauth_cred_get()->cr_gid;
+               pinfo->psem_uid = kauth_getuid();
+               pinfo->psem_gid = kauth_getgid();
                bcopy(pnbuf, &pinfo->psem_name[0], PSEMNAMLEN);
                pinfo->psem_name[PSEMNAMLEN]= 0;
                pinfo->psem_flags &= ~PSEM_DEFINED;
                pinfo->psem_flags |= PSEM_ALLOCATED;
-               pinfo->sem_proc = p;
+               pinfo->psem_creator_pid = p->p_pid;
+               pinfo->psem_creator_uniqueid = p->p_uniqueid;
                
 #if CONFIG_MACF
                error = mac_posixsem_check_create(kauth_cred_get(), nameptr);
@@ -593,7 +602,6 @@ sem_open(proc_t p, struct sem_open_args *uap, user_addr_t *retval)
 
        proc_fdlock(p);
        fp->f_flag = fmode & FMASK;
-       fp->f_type = DTYPE_PSXSEM;
        fp->f_ops = &psemops;
        fp->f_data = (caddr_t)new_pnode;
        procfdtbl_releasefd(p, indx, NULL);
@@ -643,39 +651,14 @@ bad:
 static int
 psem_access(struct pseminfo *pinfo, int mode, kauth_cred_t cred)
 {
-       mode_t mask;
-       int is_member;
+       int mode_req = ((mode & FREAD) ? S_IRUSR : 0) |
+                      ((mode & FWRITE) ? S_IWUSR : 0);
 
        /* Otherwise, user id 0 always gets access. */
        if (!suser(cred, NULL))
                return (0);
 
-       mask = 0;
-
-       /* Otherwise, check the owner. */
-       if (kauth_cred_getuid(cred) == pinfo->psem_uid) {
-               if (mode & FREAD)
-                       mask |= S_IRUSR;
-               if (mode & FWRITE)
-                       mask |= S_IWUSR;
-               return ((pinfo->psem_mode & mask) == mask ? 0 : EACCES);
-       }
-
-       /* Otherwise, check the groups. */
-       if (kauth_cred_ismember_gid(cred, pinfo->psem_gid, &is_member) == 0 && is_member) {
-               if (mode & FREAD)
-                       mask |= S_IRGRP;
-               if (mode & FWRITE)
-                       mask |= S_IWGRP;
-               return ((pinfo->psem_mode & mask) == mask ? 0 : EACCES);
-       }
-
-       /* Otherwise, check everyone else. */
-       if (mode & FREAD)
-               mask |= S_IROTH;
-       if (mode & FWRITE)
-               mask |= S_IWOTH;
-       return ((pinfo->psem_mode & mask) == mask ? 0 : EACCES);
+       return(posix_cred_access(cred, pinfo->psem_uid, pinfo->psem_gid, pinfo->psem_mode, mode_req));
 }
 
 int
@@ -809,10 +792,11 @@ sem_close(proc_t p, struct sem_close_args *uap, __unused int32_t *retval)
                proc_fdunlock(p);
                return(error);
        }
+       procfdtbl_markclosefd(p, fd);
        fileproc_drain(p, fp);
        fdrelse(p, fd);
        error = closef_locked(fp, fp->f_fglob, p);
-       FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
+       fileproc_free(fp);
        proc_fdunlock(p);
        return(error);
 }