| 646 | } |
| 647 | |
| 648 | static int |
| 649 | udp6_getcred(SYSCTL_HANDLER_ARGS) |
| 650 | { |
| 651 | struct xucred xuc; |
| 652 | struct sockaddr_in6 addrs[2]; |
| 653 | struct epoch_tracker et; |
| 654 | struct inpcb *inp; |
| 655 | int error; |
| 656 | |
| 657 | error = priv_check(req->td, PRIV_NETINET_GETCRED); |
| 658 | if (error) |
| 659 | return (error); |
| 660 | |
| 661 | if (req->newlen != sizeof(addrs)) |
| 662 | return (EINVAL); |
| 663 | if (req->oldlen != sizeof(struct xucred)) |
| 664 | return (EINVAL); |
| 665 | error = SYSCTL_IN(req, addrs, sizeof(addrs)); |
| 666 | if (error) |
| 667 | return (error); |
| 668 | if ((error = sa6_embedscope(&addrs[0], V_ip6_use_defzone)) != 0 || |
| 669 | (error = sa6_embedscope(&addrs[1], V_ip6_use_defzone)) != 0) { |
| 670 | return (error); |
| 671 | } |
| 672 | NET_EPOCH_ENTER(et); |
| 673 | inp = in6_pcblookup(&V_udbinfo, &addrs[1].sin6_addr, |
| 674 | addrs[1].sin6_port, &addrs[0].sin6_addr, addrs[0].sin6_port, |
| 675 | INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL); |
| 676 | NET_EPOCH_EXIT(et); |
| 677 | if (inp != NULL) { |
| 678 | INP_RLOCK_ASSERT(inp); |
| 679 | if (inp->inp_socket == NULL) |
| 680 | error = ENOENT; |
| 681 | if (error == 0) |
| 682 | error = cr_canseesocket(req->td->td_ucred, |
| 683 | inp->inp_socket); |
| 684 | if (error == 0) |
| 685 | cru2x(inp->inp_cred, &xuc); |
| 686 | INP_RUNLOCK(inp); |
| 687 | } else |
| 688 | error = ENOENT; |
| 689 | if (error == 0) |
| 690 | error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); |
| 691 | return (error); |
| 692 | } |
| 693 | |
| 694 | SYSCTL_PROC(_net_inet6_udp6, OID_AUTO, getcred, |
| 695 | CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, |
nothing calls this directly
no test coverage detected