| 496 | } |
| 497 | |
| 498 | int |
| 499 | kern_msgctl(struct thread *td, int msqid, int cmd, struct msqid_ds *msqbuf) |
| 500 | { |
| 501 | int rval, error, msqix; |
| 502 | struct msqid_kernel *msqkptr; |
| 503 | struct prison *rpr; |
| 504 | |
| 505 | rpr = msg_find_prison(td->td_ucred); |
| 506 | if (rpr == NULL) |
| 507 | return (ENOSYS); |
| 508 | |
| 509 | AUDIT_ARG_SVIPC_CMD(cmd); |
| 510 | AUDIT_ARG_SVIPC_ID(msqid); |
| 511 | msqix = IPCID_TO_IX(msqid); |
| 512 | |
| 513 | if (msqix < 0 || msqix >= msginfo.msgmni) { |
| 514 | DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqix, |
| 515 | msginfo.msgmni)); |
| 516 | return (EINVAL); |
| 517 | } |
| 518 | |
| 519 | msqkptr = &msqids[msqix]; |
| 520 | |
| 521 | mtx_lock(&msq_mtx); |
| 522 | if (msqkptr->u.msg_qbytes == 0) { |
| 523 | DPRINTF(("no such msqid\n")); |
| 524 | error = EINVAL; |
| 525 | goto done2; |
| 526 | } |
| 527 | if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(msqid)) { |
| 528 | DPRINTF(("wrong sequence number\n")); |
| 529 | error = EINVAL; |
| 530 | goto done2; |
| 531 | } |
| 532 | |
| 533 | error = msq_prison_cansee(rpr, msqkptr); |
| 534 | if (error != 0) { |
| 535 | DPRINTF(("requester can't see prison\n")); |
| 536 | goto done2; |
| 537 | } |
| 538 | |
| 539 | #ifdef MAC |
| 540 | error = mac_sysvmsq_check_msqctl(td->td_ucred, msqkptr, cmd); |
| 541 | if (error != 0) |
| 542 | goto done2; |
| 543 | #endif |
| 544 | |
| 545 | error = 0; |
| 546 | rval = 0; |
| 547 | |
| 548 | switch (cmd) { |
| 549 | case IPC_RMID: |
| 550 | { |
| 551 | #ifdef MAC |
| 552 | struct msg *msghdr; |
| 553 | #endif |
| 554 | if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_M))) |
| 555 | goto done2; |
no test coverage detected