| 690 | } |
| 691 | |
| 692 | int |
| 693 | kern_semctl(struct thread *td, int semid, int semnum, int cmd, |
| 694 | union semun *arg, register_t *rval) |
| 695 | { |
| 696 | u_short *array; |
| 697 | struct ucred *cred = td->td_ucred; |
| 698 | int i, error; |
| 699 | struct prison *rpr; |
| 700 | struct semid_ds *sbuf; |
| 701 | struct semid_kernel *semakptr; |
| 702 | struct mtx *sema_mtxp; |
| 703 | u_short usval, count; |
| 704 | int semidx; |
| 705 | |
| 706 | DPRINTF(("call to semctl(%d, %d, %d, 0x%p)\n", |
| 707 | semid, semnum, cmd, arg)); |
| 708 | |
| 709 | AUDIT_ARG_SVIPC_CMD(cmd); |
| 710 | AUDIT_ARG_SVIPC_ID(semid); |
| 711 | |
| 712 | rpr = sem_find_prison(td->td_ucred); |
| 713 | if (sem == NULL) |
| 714 | return (ENOSYS); |
| 715 | |
| 716 | array = NULL; |
| 717 | |
| 718 | switch(cmd) { |
| 719 | case SEM_STAT: |
| 720 | /* |
| 721 | * For this command we assume semid is an array index |
| 722 | * rather than an IPC id. |
| 723 | */ |
| 724 | if (semid < 0 || semid >= seminfo.semmni) |
| 725 | return (EINVAL); |
| 726 | semakptr = &sema[semid]; |
| 727 | sema_mtxp = &sema_mtx[semid]; |
| 728 | mtx_lock(sema_mtxp); |
| 729 | if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0) { |
| 730 | error = EINVAL; |
| 731 | goto done2; |
| 732 | } |
| 733 | if ((error = sem_prison_cansee(rpr, semakptr))) |
| 734 | goto done2; |
| 735 | if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R))) |
| 736 | goto done2; |
| 737 | #ifdef MAC |
| 738 | error = mac_sysvsem_check_semctl(cred, semakptr, cmd); |
| 739 | if (error != 0) |
| 740 | goto done2; |
| 741 | #endif |
| 742 | bcopy(&semakptr->u, arg->buf, sizeof(struct semid_ds)); |
| 743 | if (cred->cr_prison != semakptr->cred->cr_prison) |
| 744 | arg->buf->sem_perm.key = IPC_PRIVATE; |
| 745 | *rval = IXSEQ_TO_IPCID(semid, semakptr->u.sem_perm); |
| 746 | mtx_unlock(sema_mtxp); |
| 747 | return (0); |
| 748 | } |
| 749 |
no test coverage detected