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 (-2 / +23 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 1168-1173 Link Here
1168
	space = sbspace(&so->so_snd);
1173
	space = sbspace(&so->so_snd);
1169
	if (flags & MSG_OOB)
1174
	if (flags & MSG_OOB)
1170
		space += 1024;
1175
		space += 1024;
1176
	if (clen > space) {
1177
		error = EMSGSIZE;
1178
		goto out;
1179
	}
1171
	space -= clen;
1180
	space -= clen;
1172
	SOCKBUF_UNLOCK(&so->so_snd);
1181
	SOCKBUF_UNLOCK(&so->so_snd);
1173
	if (resid > space) {
1182
	if (resid > space) {
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) {
Lines 1426-1433 Link Here
1426
				so->so_options &= ~SO_DONTROUTE;
1444
				so->so_options &= ~SO_DONTROUTE;
1427
				SOCK_UNLOCK(so);
1445
				SOCK_UNLOCK(so);
1428
			}
1446
			}
1429
			clen = 0;
1447
			if (control) {
1430
			control = NULL;
1448
				control = NULL;
1449
				space += clen;
1450
				clen = 0;
1451
			}
1431
			top = NULL;
1452
			top = NULL;
1432
			if (error)
1453
			if (error)
1433
				goto release;
1454
				goto release;
(-)kern/uipc_usrreq.c (-23 / +55 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
	UNP_PCB_LOCK(unp);
795
	unp2 = unp->unp_conn;
796
797
	if (*pcontrol != NULL && (error = unp_internalize(pcontrol, td))) {
798
		UNP_PCB_UNLOCK(unp);
799
		return (error);
800
	}
801
802
	/* Lockless read. */
803
	if (unp2->unp_flags & UNP_WANTCRED) {
804
		switch (so->so_type) {
805
		case SOCK_SEQPACKET:
806
		case SOCK_STREAM:
807
			/* Credentials are passed only once on SOCK_STREAM. */
808
			UNP_PCB_LOCK(unp2);
809
			if (unp2->unp_flags & UNP_WANTCRED) {
810
				unp2->unp_flags &= ~UNP_WANTCRED;
811
				error = unp_addsockcred(pcontrol, td);
812
			}
813
			UNP_PCB_UNLOCK(unp2);
814
			break;
815
		case SOCK_DGRAM:
816
			error = unp_addsockcred(pcontrol, td);
817
			break;
818
		}
819
	}
820
821
	UNP_PCB_UNLOCK(unp);
822
	return (error);
823
}
824
825
static int
785
uipc_rcvd(struct socket *so, int flags)
826
uipc_rcvd(struct socket *so, int flags)
786
{
827
{
787
	struct unpcb *unp, *unp2;
828
	struct unpcb *unp, *unp2;
Lines 845-852 Link Here
845
		error = EOPNOTSUPP;
886
		error = EOPNOTSUPP;
846
		goto release;
887
		goto release;
847
	}
888
	}
848
	if (control != NULL && (error = unp_internalize(&control, td)))
849
		goto release;
850
	if ((nam != NULL) || (flags & PRUS_EOF))
889
	if ((nam != NULL) || (flags & PRUS_EOF))
851
		UNP_LINK_WLOCK();
890
		UNP_LINK_WLOCK();
852
	else
891
	else
Lines 880-888 Link Here
880
			error = ENOTCONN;
919
			error = ENOTCONN;
881
			break;
920
			break;
882
		}
921
		}
883
		/* Lockless read. */
884
		if (unp2->unp_flags & UNP_WANTCRED)
885
			control = unp_addsockcred(td, control);
886
		UNP_PCB_LOCK(unp);
922
		UNP_PCB_LOCK(unp);
887
		if (unp->unp_addr != NULL)
923
		if (unp->unp_addr != NULL)
888
			from = (struct sockaddr *)unp->unp_addr;
924
			from = (struct sockaddr *)unp->unp_addr;
Lines 949-962 Link Here
949
		so2 = unp2->unp_socket;
985
		so2 = unp2->unp_socket;
950
		UNP_PCB_LOCK(unp2);
986
		UNP_PCB_LOCK(unp2);
951
		SOCKBUF_LOCK(&so2->so_rcv);
987
		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
		/*
988
		/*
961
		 * Send to paired receive port, and then reduce send buffer
989
		 * Send to paired receive port, and then reduce send buffer
962
		 * hiwater marks to maintain backpressure.  Wake up readers.
990
		 * hiwater marks to maintain backpressure.  Wake up readers.
Lines 964-972 Link Here
964
		switch (so->so_type) {
992
		switch (so->so_type) {
965
		case SOCK_STREAM:
993
		case SOCK_STREAM:
966
			if (control != NULL) {
994
			if (control != NULL) {
967
				if (sbappendcontrol_locked(&so2->so_rcv, m,
995
				sbappendcontrol_locked(&so2->so_rcv, m, control);
968
				    control))
996
				control = NULL;
969
					control = NULL;
970
			} else
997
			} else
971
				sbappend_locked(&so2->so_rcv, m);
998
				sbappend_locked(&so2->so_rcv, m);
972
			break;
999
			break;
Lines 1114-1119 Link Here
1114
	.pru_disconnect =	uipc_disconnect,
1141
	.pru_disconnect =	uipc_disconnect,
1115
	.pru_listen =		uipc_listen,
1142
	.pru_listen =		uipc_listen,
1116
	.pru_peeraddr =		uipc_peeraddr,
1143
	.pru_peeraddr =		uipc_peeraddr,
1144
	.pru_finalizecontrol =	uipc_finalizecontrol,
1117
	.pru_rcvd =		uipc_rcvd,
1145
	.pru_rcvd =		uipc_rcvd,
1118
	.pru_send =		uipc_send,
1146
	.pru_send =		uipc_send,
1119
	.pru_sense =		uipc_sense,
1147
	.pru_sense =		uipc_sense,
Lines 1136-1141 Link Here
1136
	.pru_disconnect =	uipc_disconnect,
1164
	.pru_disconnect =	uipc_disconnect,
1137
	.pru_listen =		uipc_listen,
1165
	.pru_listen =		uipc_listen,
1138
	.pru_peeraddr =		uipc_peeraddr,
1166
	.pru_peeraddr =		uipc_peeraddr,
1167
	.pru_finalizecontrol =	uipc_finalizecontrol,
1139
	.pru_rcvd =		uipc_rcvd,
1168
	.pru_rcvd =		uipc_rcvd,
1140
	.pru_send =		uipc_send,
1169
	.pru_send =		uipc_send,
1141
	.pru_sense =		uipc_sense,
1170
	.pru_sense =		uipc_sense,
Lines 1158-1163 Link Here
1158
	.pru_disconnect =	uipc_disconnect,
1187
	.pru_disconnect =	uipc_disconnect,
1159
	.pru_listen =		uipc_listen,
1188
	.pru_listen =		uipc_listen,
1160
	.pru_peeraddr =		uipc_peeraddr,
1189
	.pru_peeraddr =		uipc_peeraddr,
1190
	.pru_finalizecontrol =	uipc_finalizecontrol,
1161
	.pru_rcvd =		uipc_rcvd,
1191
	.pru_rcvd =		uipc_rcvd,
1162
	.pru_send =		uipc_send,
1192
	.pru_send =		uipc_send,
1163
	.pru_sense =		uipc_sense,
1193
	.pru_sense =		uipc_sense,
Lines 1747-1753 Link Here
1747
			    SCM_RIGHTS, SOL_SOCKET);
1777
			    SCM_RIGHTS, SOL_SOCKET);
1748
			if (*controlp == NULL) {
1778
			if (*controlp == NULL) {
1749
				FILEDESC_XUNLOCK(fdesc);
1779
				FILEDESC_XUNLOCK(fdesc);
1750
				error = E2BIG;
1780
				error = ENOBUFS;
1751
				unp_freerights(fdep, newfds);
1781
				unp_freerights(fdep, newfds);
1752
				goto next;
1782
				goto next;
1753
			}
1783
			}
Lines 1928-1934 Link Here
1928
			    SCM_RIGHTS, SOL_SOCKET);
1958
			    SCM_RIGHTS, SOL_SOCKET);
1929
			if (*controlp == NULL) {
1959
			if (*controlp == NULL) {
1930
				FILEDESC_SUNLOCK(fdesc);
1960
				FILEDESC_SUNLOCK(fdesc);
1931
				error = E2BIG;
1961
				error = ENOBUFS;
1932
				goto out;
1962
				goto out;
1933
			}
1963
			}
1934
			fdp = data;
1964
			fdp = data;
Lines 1992-2000 Link Here
1992
	return (error);
2022
	return (error);
1993
}
2023
}
1994
2024
1995
static struct mbuf *
2025
static int
1996
unp_addsockcred(struct thread *td, struct mbuf *control)
2026
unp_addsockcred(struct mbuf **pcontrol, struct thread *td)
1997
{
2027
{
2028
	struct mbuf *control = *pcontrol;
1998
	struct mbuf *m, *n, *n_prev;
2029
	struct mbuf *m, *n, *n_prev;
1999
	struct sockcred *sc;
2030
	struct sockcred *sc;
2000
	const struct cmsghdr *cm;
2031
	const struct cmsghdr *cm;
Lines 2004-2010 Link Here
2004
	ngroups = MIN(td->td_ucred->cr_ngroups, CMGROUP_MAX);
2035
	ngroups = MIN(td->td_ucred->cr_ngroups, CMGROUP_MAX);
2005
	m = sbcreatecontrol(NULL, SOCKCREDSIZE(ngroups), SCM_CREDS, SOL_SOCKET);
2036
	m = sbcreatecontrol(NULL, SOCKCREDSIZE(ngroups), SCM_CREDS, SOL_SOCKET);
2006
	if (m == NULL)
2037
	if (m == NULL)
2007
		return (control);
2038
		return (ENOBUFS);
2008
2039
2009
	sc = (struct sockcred *) CMSG_DATA(mtod(m, struct cmsghdr *));
2040
	sc = (struct sockcred *) CMSG_DATA(mtod(m, struct cmsghdr *));
2010
	sc->sc_uid = td->td_ucred->cr_ruid;
2041
	sc->sc_uid = td->td_ucred->cr_ruid;
Lines 2038-2044 Link Here
2038
2069
2039
	/* Prepend it to the head. */
2070
	/* Prepend it to the head. */
2040
	m->m_next = control;
2071
	m->m_next = control;
2041
	return (m);
2072
	*pcontrol = m;
2073
	return (0);
2042
}
2074
}
2043
2075
2044
static struct unpcb *
2076
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