| 585 | } |
| 586 | |
| 587 | static int |
| 588 | uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td) |
| 589 | { |
| 590 | struct sockaddr_un *soun = (struct sockaddr_un *)nam; |
| 591 | struct vattr vattr; |
| 592 | int error, namelen; |
| 593 | struct nameidata nd; |
| 594 | struct unpcb *unp; |
| 595 | struct vnode *vp; |
| 596 | struct mount *mp; |
| 597 | cap_rights_t rights; |
| 598 | char *buf; |
| 599 | |
| 600 | if (nam->sa_family != AF_UNIX) |
| 601 | return (EAFNOSUPPORT); |
| 602 | |
| 603 | unp = sotounpcb(so); |
| 604 | KASSERT(unp != NULL, ("uipc_bind: unp == NULL")); |
| 605 | |
| 606 | if (soun->sun_len > sizeof(struct sockaddr_un)) |
| 607 | return (EINVAL); |
| 608 | namelen = soun->sun_len - offsetof(struct sockaddr_un, sun_path); |
| 609 | if (namelen <= 0) |
| 610 | return (EINVAL); |
| 611 | |
| 612 | /* |
| 613 | * We don't allow simultaneous bind() calls on a single UNIX domain |
| 614 | * socket, so flag in-progress operations, and return an error if an |
| 615 | * operation is already in progress. |
| 616 | * |
| 617 | * Historically, we have not allowed a socket to be rebound, so this |
| 618 | * also returns an error. Not allowing re-binding simplifies the |
| 619 | * implementation and avoids a great many possible failure modes. |
| 620 | */ |
| 621 | UNP_PCB_LOCK(unp); |
| 622 | if (unp->unp_vnode != NULL) { |
| 623 | UNP_PCB_UNLOCK(unp); |
| 624 | return (EINVAL); |
| 625 | } |
| 626 | if (unp->unp_flags & UNP_BINDING) { |
| 627 | UNP_PCB_UNLOCK(unp); |
| 628 | return (EALREADY); |
| 629 | } |
| 630 | unp->unp_flags |= UNP_BINDING; |
| 631 | UNP_PCB_UNLOCK(unp); |
| 632 | |
| 633 | buf = malloc(namelen + 1, M_TEMP, M_WAITOK); |
| 634 | bcopy(soun->sun_path, buf, namelen); |
| 635 | buf[namelen] = 0; |
| 636 | |
| 637 | restart: |
| 638 | NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME | NOCACHE, |
| 639 | UIO_SYSSPACE, buf, fd, cap_rights_init_one(&rights, CAP_BINDAT), |
| 640 | td); |
| 641 | /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */ |
| 642 | error = namei(&nd); |
| 643 | if (error) |
| 644 | goto error; |
no test coverage detected