Lines 290-296
Link Here
|
290 |
static void unp_internalize_fp(struct file *); |
290 |
static void unp_internalize_fp(struct file *); |
291 |
static int unp_externalize(struct mbuf *, struct mbuf **, int); |
291 |
static int unp_externalize(struct mbuf *, struct mbuf **, int); |
292 |
static int unp_externalize_fp(struct file *); |
292 |
static int unp_externalize_fp(struct file *); |
293 |
static struct mbuf *unp_addsockcred(struct thread *, struct mbuf *); |
293 |
static int unp_addsockcred(struct mbuf **, struct thread *); |
294 |
static void unp_process_defers(void * __unused, int); |
294 |
static void unp_process_defers(void * __unused, int); |
295 |
|
295 |
|
296 |
/* |
296 |
/* |
Lines 782-787
Link Here
|
782 |
} |
782 |
} |
783 |
|
783 |
|
784 |
static int |
784 |
static int |
|
|
785 |
uipc_finalizecontrol(struct socket *so, int flags, struct mbuf **pcontrol, |
786 |
struct thread *td) |
787 |
{ |
788 |
struct unpcb *unp, *unp2; |
789 |
int error = 0; |
790 |
|
791 |
unp = sotounpcb(so); |
792 |
KASSERT(unp != NULL, ("uipc_finalizecontrol: unp == NULL")); |
793 |
|
794 |
unp2 = unp->unp_conn; |
795 |
|
796 |
if (*pcontrol != NULL && (error = unp_internalize(pcontrol, td))) |
797 |
return (error); |
798 |
|
799 |
/* Lockless read, ignore when not connected. */ |
800 |
if (unp2 && unp2->unp_flags & UNP_WANTCRED) { |
801 |
switch (so->so_type) { |
802 |
case SOCK_SEQPACKET: |
803 |
case SOCK_STREAM: |
804 |
/* Credentials are passed only once on streams */ |
805 |
UNP_PCB_LOCK(unp2); |
806 |
if (unp2->unp_flags & UNP_WANTCRED) { |
807 |
unp2->unp_flags &= ~UNP_WANTCRED; |
808 |
error = unp_addsockcred(pcontrol, td); |
809 |
} |
810 |
UNP_PCB_UNLOCK(unp2); |
811 |
break; |
812 |
case SOCK_DGRAM: |
813 |
error = unp_addsockcred(pcontrol, td); |
814 |
break; |
815 |
} |
816 |
} |
817 |
|
818 |
return (error); |
819 |
} |
820 |
|
821 |
static int |
785 |
uipc_rcvd(struct socket *so, int flags) |
822 |
uipc_rcvd(struct socket *so, int flags) |
786 |
{ |
823 |
{ |
787 |
struct unpcb *unp, *unp2; |
824 |
struct unpcb *unp, *unp2; |
Lines 845-852
Link Here
|
845 |
error = EOPNOTSUPP; |
882 |
error = EOPNOTSUPP; |
846 |
goto release; |
883 |
goto release; |
847 |
} |
884 |
} |
848 |
if (control != NULL && (error = unp_internalize(&control, td))) |
|
|
849 |
goto release; |
850 |
if ((nam != NULL) || (flags & PRUS_EOF)) |
885 |
if ((nam != NULL) || (flags & PRUS_EOF)) |
851 |
UNP_LINK_WLOCK(); |
886 |
UNP_LINK_WLOCK(); |
852 |
else |
887 |
else |
Lines 880-888
Link Here
|
880 |
error = ENOTCONN; |
915 |
error = ENOTCONN; |
881 |
break; |
916 |
break; |
882 |
} |
917 |
} |
883 |
/* Lockless read. */ |
|
|
884 |
if (unp2->unp_flags & UNP_WANTCRED) |
885 |
control = unp_addsockcred(td, control); |
886 |
UNP_PCB_LOCK(unp); |
918 |
UNP_PCB_LOCK(unp); |
887 |
if (unp->unp_addr != NULL) |
919 |
if (unp->unp_addr != NULL) |
888 |
from = (struct sockaddr *)unp->unp_addr; |
920 |
from = (struct sockaddr *)unp->unp_addr; |
Lines 949-962
Link Here
|
949 |
so2 = unp2->unp_socket; |
981 |
so2 = unp2->unp_socket; |
950 |
UNP_PCB_LOCK(unp2); |
982 |
UNP_PCB_LOCK(unp2); |
951 |
SOCKBUF_LOCK(&so2->so_rcv); |
983 |
SOCKBUF_LOCK(&so2->so_rcv); |
952 |
if (unp2->unp_flags & UNP_WANTCRED) { |
|
|
953 |
/* |
954 |
* Credentials are passed only once on SOCK_STREAM |
955 |
* and SOCK_SEQPACKET. |
956 |
*/ |
957 |
unp2->unp_flags &= ~UNP_WANTCRED; |
958 |
control = unp_addsockcred(td, control); |
959 |
} |
960 |
/* |
984 |
/* |
961 |
* Send to paired receive port, and then reduce send buffer |
985 |
* Send to paired receive port, and then reduce send buffer |
962 |
* hiwater marks to maintain backpressure. Wake up readers. |
986 |
* hiwater marks to maintain backpressure. Wake up readers. |
Lines 964-972
Link Here
|
964 |
switch (so->so_type) { |
988 |
switch (so->so_type) { |
965 |
case SOCK_STREAM: |
989 |
case SOCK_STREAM: |
966 |
if (control != NULL) { |
990 |
if (control != NULL) { |
967 |
if (sbappendcontrol_locked(&so2->so_rcv, m, |
991 |
sbappendcontrol_locked(&so2->so_rcv, m, |
968 |
control)) |
992 |
control); |
969 |
control = NULL; |
993 |
control = NULL; |
970 |
} else |
994 |
} else |
971 |
sbappend_locked(&so2->so_rcv, m); |
995 |
sbappend_locked(&so2->so_rcv, m); |
972 |
break; |
996 |
break; |
Lines 981-986
Link Here
|
981 |
break; |
1005 |
break; |
982 |
} |
1006 |
} |
983 |
} |
1007 |
} |
|
|
1008 |
m = NULL; |
984 |
|
1009 |
|
985 |
/* |
1010 |
/* |
986 |
* XXXRW: While fine for SOCK_STREAM, this conflates maximum |
1011 |
* XXXRW: While fine for SOCK_STREAM, this conflates maximum |
Lines 1004-1010
Link Here
|
1004 |
SOCKBUF_UNLOCK(&so->so_snd); |
1029 |
SOCKBUF_UNLOCK(&so->so_snd); |
1005 |
unp2->unp_cc = sbcc; |
1030 |
unp2->unp_cc = sbcc; |
1006 |
UNP_PCB_UNLOCK(unp2); |
1031 |
UNP_PCB_UNLOCK(unp2); |
1007 |
m = NULL; |
|
|
1008 |
break; |
1032 |
break; |
1009 |
|
1033 |
|
1010 |
default: |
1034 |
default: |
Lines 1114-1119
Link Here
|
1114 |
.pru_disconnect = uipc_disconnect, |
1138 |
.pru_disconnect = uipc_disconnect, |
1115 |
.pru_listen = uipc_listen, |
1139 |
.pru_listen = uipc_listen, |
1116 |
.pru_peeraddr = uipc_peeraddr, |
1140 |
.pru_peeraddr = uipc_peeraddr, |
|
|
1141 |
.pru_finalizecontrol = uipc_finalizecontrol, |
1117 |
.pru_rcvd = uipc_rcvd, |
1142 |
.pru_rcvd = uipc_rcvd, |
1118 |
.pru_send = uipc_send, |
1143 |
.pru_send = uipc_send, |
1119 |
.pru_sense = uipc_sense, |
1144 |
.pru_sense = uipc_sense, |
Lines 1136-1141
Link Here
|
1136 |
.pru_disconnect = uipc_disconnect, |
1161 |
.pru_disconnect = uipc_disconnect, |
1137 |
.pru_listen = uipc_listen, |
1162 |
.pru_listen = uipc_listen, |
1138 |
.pru_peeraddr = uipc_peeraddr, |
1163 |
.pru_peeraddr = uipc_peeraddr, |
|
|
1164 |
.pru_finalizecontrol = uipc_finalizecontrol, |
1139 |
.pru_rcvd = uipc_rcvd, |
1165 |
.pru_rcvd = uipc_rcvd, |
1140 |
.pru_send = uipc_send, |
1166 |
.pru_send = uipc_send, |
1141 |
.pru_sense = uipc_sense, |
1167 |
.pru_sense = uipc_sense, |
Lines 1158-1163
Link Here
|
1158 |
.pru_disconnect = uipc_disconnect, |
1184 |
.pru_disconnect = uipc_disconnect, |
1159 |
.pru_listen = uipc_listen, |
1185 |
.pru_listen = uipc_listen, |
1160 |
.pru_peeraddr = uipc_peeraddr, |
1186 |
.pru_peeraddr = uipc_peeraddr, |
|
|
1187 |
.pru_finalizecontrol = uipc_finalizecontrol, |
1161 |
.pru_rcvd = uipc_rcvd, |
1188 |
.pru_rcvd = uipc_rcvd, |
1162 |
.pru_send = uipc_send, |
1189 |
.pru_send = uipc_send, |
1163 |
.pru_sense = uipc_sense, |
1190 |
.pru_sense = uipc_sense, |
Lines 1747-1753
Link Here
|
1747 |
SCM_RIGHTS, SOL_SOCKET); |
1774 |
SCM_RIGHTS, SOL_SOCKET); |
1748 |
if (*controlp == NULL) { |
1775 |
if (*controlp == NULL) { |
1749 |
FILEDESC_XUNLOCK(fdesc); |
1776 |
FILEDESC_XUNLOCK(fdesc); |
1750 |
error = E2BIG; |
1777 |
error = ENOBUFS; |
1751 |
unp_freerights(fdep, newfds); |
1778 |
unp_freerights(fdep, newfds); |
1752 |
goto next; |
1779 |
goto next; |
1753 |
} |
1780 |
} |
Lines 1928-1934
Link Here
|
1928 |
SCM_RIGHTS, SOL_SOCKET); |
1955 |
SCM_RIGHTS, SOL_SOCKET); |
1929 |
if (*controlp == NULL) { |
1956 |
if (*controlp == NULL) { |
1930 |
FILEDESC_SUNLOCK(fdesc); |
1957 |
FILEDESC_SUNLOCK(fdesc); |
1931 |
error = E2BIG; |
1958 |
error = ENOBUFS; |
1932 |
goto out; |
1959 |
goto out; |
1933 |
} |
1960 |
} |
1934 |
fdp = data; |
1961 |
fdp = data; |
Lines 1992-2000
Link Here
|
1992 |
return (error); |
2019 |
return (error); |
1993 |
} |
2020 |
} |
1994 |
|
2021 |
|
1995 |
static struct mbuf * |
2022 |
static int |
1996 |
unp_addsockcred(struct thread *td, struct mbuf *control) |
2023 |
unp_addsockcred(struct mbuf **pcontrol, struct thread *td) |
1997 |
{ |
2024 |
{ |
|
|
2025 |
struct mbuf *control = *pcontrol; |
1998 |
struct mbuf *m, *n, *n_prev; |
2026 |
struct mbuf *m, *n, *n_prev; |
1999 |
struct sockcred *sc; |
2027 |
struct sockcred *sc; |
2000 |
const struct cmsghdr *cm; |
2028 |
const struct cmsghdr *cm; |
Lines 2004-2010
Link Here
|
2004 |
ngroups = MIN(td->td_ucred->cr_ngroups, CMGROUP_MAX); |
2032 |
ngroups = MIN(td->td_ucred->cr_ngroups, CMGROUP_MAX); |
2005 |
m = sbcreatecontrol(NULL, SOCKCREDSIZE(ngroups), SCM_CREDS, SOL_SOCKET); |
2033 |
m = sbcreatecontrol(NULL, SOCKCREDSIZE(ngroups), SCM_CREDS, SOL_SOCKET); |
2006 |
if (m == NULL) |
2034 |
if (m == NULL) |
2007 |
return (control); |
2035 |
return (ENOBUFS); |
2008 |
|
2036 |
|
2009 |
sc = (struct sockcred *) CMSG_DATA(mtod(m, struct cmsghdr *)); |
2037 |
sc = (struct sockcred *) CMSG_DATA(mtod(m, struct cmsghdr *)); |
2010 |
sc->sc_uid = td->td_ucred->cr_ruid; |
2038 |
sc->sc_uid = td->td_ucred->cr_ruid; |
Lines 2038-2044
Link Here
|
2038 |
|
2066 |
|
2039 |
/* Prepend it to the head. */ |
2067 |
/* Prepend it to the head. */ |
2040 |
m->m_next = control; |
2068 |
m->m_next = control; |
2041 |
return (m); |
2069 |
*pcontrol = m; |
|
|
2070 |
return (0); |
2042 |
} |
2071 |
} |
2043 |
|
2072 |
|
2044 |
static struct unpcb * |
2073 |
static struct unpcb * |