| 964 | }; |
| 965 | #endif |
| 966 | int |
| 967 | sys_semget(struct thread *td, struct semget_args *uap) |
| 968 | { |
| 969 | int semid, error = 0; |
| 970 | int key = uap->key; |
| 971 | int nsems = uap->nsems; |
| 972 | int semflg = uap->semflg; |
| 973 | struct ucred *cred = td->td_ucred; |
| 974 | |
| 975 | DPRINTF(("semget(0x%x, %d, 0%o)\n", key, nsems, semflg)); |
| 976 | |
| 977 | AUDIT_ARG_VALUE(semflg); |
| 978 | |
| 979 | if (sem_find_prison(cred) == NULL) |
| 980 | return (ENOSYS); |
| 981 | |
| 982 | mtx_lock(&sem_mtx); |
| 983 | if (key != IPC_PRIVATE) { |
| 984 | for (semid = 0; semid < seminfo.semmni; semid++) { |
| 985 | if ((sema[semid].u.sem_perm.mode & SEM_ALLOC) && |
| 986 | sema[semid].cred != NULL && |
| 987 | sema[semid].cred->cr_prison == cred->cr_prison && |
| 988 | sema[semid].u.sem_perm.key == key) |
| 989 | break; |
| 990 | } |
| 991 | if (semid < seminfo.semmni) { |
| 992 | AUDIT_ARG_SVIPC_ID(semid); |
| 993 | DPRINTF(("found public key\n")); |
| 994 | if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) { |
| 995 | DPRINTF(("not exclusive\n")); |
| 996 | error = EEXIST; |
| 997 | goto done2; |
| 998 | } |
| 999 | if ((error = ipcperm(td, &sema[semid].u.sem_perm, |
| 1000 | semflg & 0700))) { |
| 1001 | goto done2; |
| 1002 | } |
| 1003 | if (nsems > 0 && sema[semid].u.sem_nsems < nsems) { |
| 1004 | DPRINTF(("too small\n")); |
| 1005 | error = EINVAL; |
| 1006 | goto done2; |
| 1007 | } |
| 1008 | #ifdef MAC |
| 1009 | error = mac_sysvsem_check_semget(cred, &sema[semid]); |
| 1010 | if (error != 0) |
| 1011 | goto done2; |
| 1012 | #endif |
| 1013 | goto found; |
| 1014 | } |
| 1015 | } |
| 1016 | |
| 1017 | DPRINTF(("need to allocate the semid_kernel\n")); |
| 1018 | if (key == IPC_PRIVATE || (semflg & IPC_CREAT)) { |
| 1019 | if (nsems <= 0 || nsems > seminfo.semmsl) { |
| 1020 | DPRINTF(("nsems out of range (0<%d<=%d)\n", nsems, |
| 1021 | seminfo.semmsl)); |
| 1022 | error = EINVAL; |
| 1023 | goto done2; |
nothing calls this directly
no test coverage detected