| 766 | }; |
| 767 | #endif |
| 768 | int |
| 769 | kern_msgsnd(struct thread *td, int msqid, const void *msgp, |
| 770 | size_t msgsz, int msgflg, long mtype) |
| 771 | { |
| 772 | int msqix, segs_needed, error = 0; |
| 773 | struct msqid_kernel *msqkptr; |
| 774 | struct msg *msghdr; |
| 775 | struct prison *rpr; |
| 776 | short next; |
| 777 | #ifdef RACCT |
| 778 | size_t saved_msgsz = 0; |
| 779 | #endif |
| 780 | |
| 781 | rpr = msg_find_prison(td->td_ucred); |
| 782 | if (rpr == NULL) |
| 783 | return (ENOSYS); |
| 784 | |
| 785 | mtx_lock(&msq_mtx); |
| 786 | AUDIT_ARG_SVIPC_ID(msqid); |
| 787 | msqix = IPCID_TO_IX(msqid); |
| 788 | |
| 789 | if (msqix < 0 || msqix >= msginfo.msgmni) { |
| 790 | DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqix, |
| 791 | msginfo.msgmni)); |
| 792 | error = EINVAL; |
| 793 | goto done2; |
| 794 | } |
| 795 | |
| 796 | msqkptr = &msqids[msqix]; |
| 797 | AUDIT_ARG_SVIPC_PERM(&msqkptr->u.msg_perm); |
| 798 | if (msqkptr->u.msg_qbytes == 0) { |
| 799 | DPRINTF(("no such message queue id\n")); |
| 800 | error = EINVAL; |
| 801 | goto done2; |
| 802 | } |
| 803 | if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(msqid)) { |
| 804 | DPRINTF(("wrong sequence number\n")); |
| 805 | error = EINVAL; |
| 806 | goto done2; |
| 807 | } |
| 808 | |
| 809 | if ((error = msq_prison_cansee(rpr, msqkptr))) { |
| 810 | DPRINTF(("requester can't see prison\n")); |
| 811 | goto done2; |
| 812 | } |
| 813 | |
| 814 | if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_W))) { |
| 815 | DPRINTF(("requester doesn't have write access\n")); |
| 816 | goto done2; |
| 817 | } |
| 818 | |
| 819 | #ifdef MAC |
| 820 | error = mac_sysvmsq_check_msqsnd(td->td_ucred, msqkptr); |
| 821 | if (error != 0) |
| 822 | goto done2; |
| 823 | #endif |
| 824 | |
| 825 | #ifdef RACCT |
no test coverage detected