View | Details | Raw Unified | Return to bug 181741 | Differences between
and this patch

Collapse All | Expand All

(-)kern/uipc_sockbuf.c (-16 / +5 lines)
Lines 688-710 Link Here
688
	return (retval);
688
	return (retval);
689
}
689
}
690
690
691
int
691
void
692
sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
692
sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
693
    struct mbuf *control)
693
    struct mbuf *control)
694
{
694
{
695
	struct mbuf *m, *n, *mlast;
695
	struct mbuf *m, *mlast;
696
	int space;
697
696
698
	SOCKBUF_LOCK_ASSERT(sb);
697
	SOCKBUF_LOCK_ASSERT(sb);
699
698
700
	if (control == 0)
699
	m_last(control)->m_next = m0;		/* concatenate data to control */
701
		panic("sbappendcontrol_locked");
702
	space = m_length(control, &n) + m_length(m0, NULL);
703
700
704
	if (space > sbspace(sb))
705
		return (0);
706
	n->m_next = m0;			/* concatenate data to control */
707
708
	SBLASTRECORDCHK(sb);
701
	SBLASTRECORDCHK(sb);
709
702
710
	for (m = control; m->m_next; m = m->m_next)
703
	for (m = control; m->m_next; m = m->m_next)
Lines 717-734 Link Here
717
	SBLASTMBUFCHK(sb);
710
	SBLASTMBUFCHK(sb);
718
711
719
	SBLASTRECORDCHK(sb);
712
	SBLASTRECORDCHK(sb);
720
	return (1);
721
}
713
}
722
714
723
int
715
void
724
sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
716
sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
725
{
717
{
726
	int retval;
727
728
	SOCKBUF_LOCK(sb);
718
	SOCKBUF_LOCK(sb);
729
	retval = sbappendcontrol_locked(sb, m0, control);
719
	sbappendcontrol_locked(sb, m0, control);
730
	SOCKBUF_UNLOCK(sb);
720
	SOCKBUF_UNLOCK(sb);
731
	return (retval);
732
}
721
}
733
722
734
/*
723
/*
(-)kern/uipc_socket.c (-1 / +19 lines)
Lines 1102-1107 Link Here
1102
	KASSERT(so->so_proto->pr_flags & PR_ATOMIC,
1102
	KASSERT(so->so_proto->pr_flags & PR_ATOMIC,
1103
	    ("sosend_dgram: !PR_ATOMIC"));
1103
	    ("sosend_dgram: !PR_ATOMIC"));
1104
1104
1105
	if (so->so_proto->pr_usrreqs->pru_finalizecontrol &&
1106
	    (error = (*so->so_proto->pr_usrreqs->pru_finalizecontrol)(so,
1107
	        flags, &control, td)))
1108
		goto out;
1109
1105
	if (uio != NULL)
1110
	if (uio != NULL)
1106
		resid = uio->uio_resid;
1111
		resid = uio->uio_resid;
1107
	else
1112
	else
Lines 1166-1175 Link Here
1166
	 * problem and need fixing.
1171
	 * problem and need fixing.
1167
	 */
1172
	 */
1168
	space = sbspace(&so->so_snd);
1173
	space = sbspace(&so->so_snd);
1174
	SOCKBUF_UNLOCK(&so->so_snd);
1169
	if (flags & MSG_OOB)
1175
	if (flags & MSG_OOB)
1170
		space += 1024;
1176
		space += 1024;
1177
	if (clen > space) {
1178
		error = EMSGSIZE;
1179
		goto out;
1180
	}
1171
	space -= clen;
1181
	space -= clen;
1172
	SOCKBUF_UNLOCK(&so->so_snd);
1173
	if (resid > space) {
1182
	if (resid > space) {
1174
		error = EMSGSIZE;
1183
		error = EMSGSIZE;
1175
		goto out;
1184
		goto out;
Lines 1269-1274 Link Here
1269
	int clen = 0, error, dontroute;
1278
	int clen = 0, error, dontroute;
1270
	int atomic = sosendallatonce(so) || top;
1279
	int atomic = sosendallatonce(so) || top;
1271
1280
1281
	if (so->so_proto->pr_usrreqs->pru_finalizecontrol &&
1282
	    (error = (*so->so_proto->pr_usrreqs->pru_finalizecontrol)(so,
1283
	        flags, &control, td)))
1284
		goto out;
1285
1272
	if (uio != NULL)
1286
	if (uio != NULL)
1273
		resid = uio->uio_resid;
1287
		resid = uio->uio_resid;
1274
	else
1288
	else
Lines 1361-1366 Link Here
1361
			goto restart;
1375
			goto restart;
1362
		}
1376
		}
1363
		SOCKBUF_UNLOCK(&so->so_snd);
1377
		SOCKBUF_UNLOCK(&so->so_snd);
1378
		if (clen > space) {
1379
			error = EMSGSIZE;
1380
			goto release;
1381
		}
1364
		space -= clen;
1382
		space -= clen;
1365
		do {
1383
		do {
1366
			if (uio == NULL) {
1384
			if (uio == NULL) {
(-)kern/uipc_usrreq.c (-24 / +53 lines)
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 *
(-)sys/protosw.h (+2 lines)
Lines 201-206 Link Here
201
	int	(*pru_listen)(struct socket *so, int backlog,
201
	int	(*pru_listen)(struct socket *so, int backlog,
202
		    struct thread *td);
202
		    struct thread *td);
203
	int	(*pru_peeraddr)(struct socket *so, struct sockaddr **nam);
203
	int	(*pru_peeraddr)(struct socket *so, struct sockaddr **nam);
204
	int	(*pru_finalizecontrol)(struct socket *so, int flags, struct mbuf **pcontrol,
205
		    struct thread *td);
204
	int	(*pru_rcvd)(struct socket *so, int flags);
206
	int	(*pru_rcvd)(struct socket *so, int flags);
205
	int	(*pru_rcvoob)(struct socket *so, struct mbuf *m, int flags);
207
	int	(*pru_rcvoob)(struct socket *so, struct mbuf *m, int flags);
206
	int	(*pru_send)(struct socket *so, int flags, struct mbuf *m,
208
	int	(*pru_send)(struct socket *so, int flags, struct mbuf *m,
(-)sys/sockbuf.h (-2 / +2 lines)
Lines 127-135 Link Here
127
	    struct mbuf *m0, struct mbuf *control);
127
	    struct mbuf *m0, struct mbuf *control);
128
int	sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
128
int	sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
129
	    struct mbuf *m0, struct mbuf *control);
129
	    struct mbuf *m0, struct mbuf *control);
130
int	sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
130
void	sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
131
	    struct mbuf *control);
131
	    struct mbuf *control);
132
int	sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
132
void	sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
133
	    struct mbuf *control);
133
	    struct mbuf *control);
134
void	sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
134
void	sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
135
void	sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
135
void	sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);

Return to bug 181741