| 487 | } |
| 488 | |
| 489 | int |
| 490 | mac_socket_label_set(struct ucred *cred, struct socket *so, |
| 491 | struct label *label) |
| 492 | { |
| 493 | int error; |
| 494 | |
| 495 | /* |
| 496 | * We acquire the socket lock when we perform the test and set, but |
| 497 | * have to release it as the pcb code needs to acquire the pcb lock, |
| 498 | * which will precede the socket lock in the lock order. However, |
| 499 | * this is fine, as any race will simply result in the inpcb being |
| 500 | * refreshed twice, but still consistently, as the inpcb code will |
| 501 | * acquire the socket lock before refreshing, holding both locks. |
| 502 | */ |
| 503 | SOCK_LOCK(so); |
| 504 | error = mac_socket_check_relabel(cred, so, label); |
| 505 | if (error) { |
| 506 | SOCK_UNLOCK(so); |
| 507 | return (error); |
| 508 | } |
| 509 | |
| 510 | mac_socket_relabel(cred, so, label); |
| 511 | SOCK_UNLOCK(so); |
| 512 | |
| 513 | /* |
| 514 | * If the protocol has expressed interest in socket layer changes, |
| 515 | * such as if it needs to propagate changes to a cached pcb label |
| 516 | * from the socket, notify it of the label change while holding the |
| 517 | * socket lock. |
| 518 | */ |
| 519 | if (so->so_proto->pr_usrreqs->pru_sosetlabel != NULL) |
| 520 | (so->so_proto->pr_usrreqs->pru_sosetlabel)(so); |
| 521 | |
| 522 | return (0); |
| 523 | } |
| 524 | |
| 525 | int |
| 526 | mac_setsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac) |
no test coverage detected