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

Collapse All | Expand All

(-)sys/kern/uipc_sockbuf.c (-16 / +5 lines)
Lines 888-910 Link Here
888
	return (retval);
888
	return (retval);
889
}
889
}
890
890
891
int
891
void
892
sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
892
sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
893
    struct mbuf *control)
893
    struct mbuf *control)
894
{
894
{
895
	struct mbuf *m, *n, *mlast;
895
	struct mbuf *m, *mlast;
896
	int space;
897
896
898
	SOCKBUF_LOCK_ASSERT(sb);
897
	SOCKBUF_LOCK_ASSERT(sb);
899
898
900
	if (control == NULL)
901
		panic("sbappendcontrol_locked");
902
	space = m_length(control, &n) + m_length(m0, NULL);
903
904
	if (space > sbspace(sb))
905
		return (0);
906
	m_clrprotoflags(m0);
899
	m_clrprotoflags(m0);
907
	n->m_next = m0;			/* concatenate data to control */
900
	m_last(control)->m_next = m0;	/* concatenate data to control */
908
901
909
	SBLASTRECORDCHK(sb);
902
	SBLASTRECORDCHK(sb);
910
903
Lines 918-935 Link Here
918
	SBLASTMBUFCHK(sb);
911
	SBLASTMBUFCHK(sb);
919
912
920
	SBLASTRECORDCHK(sb);
913
	SBLASTRECORDCHK(sb);
921
	return (1);
922
}
914
}
923
915
924
int
916
void
925
sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
917
sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
926
{
918
{
927
	int retval;
928
929
	SOCKBUF_LOCK(sb);
919
	SOCKBUF_LOCK(sb);
930
	retval = sbappendcontrol_locked(sb, m0, control);
920
	sbappendcontrol_locked(sb, m0, control);
931
	SOCKBUF_UNLOCK(sb);
921
	SOCKBUF_UNLOCK(sb);
932
	return (retval);
933
}
922
}
934
923
935
/*
924
/*
(-)sys/kern/uipc_socket.c (-13 / +50 lines)
Lines 1049-1054 Link Here
1049
1049
1050
#define	SBLOCKWAIT(f)	(((f) & MSG_DONTWAIT) ? 0 : SBL_WAIT)
1050
#define	SBLOCKWAIT(f)	(((f) & MSG_DONTWAIT) ? 0 : SBL_WAIT)
1051
1051
1052
/*
1053
 * Like sbspace(&so->so_snd), but allow extra room for  MSG_OOB.
1054
 *
1055
 * It's not clear whether the magic 1024 number is sensible, but
1056
 * at least it's now in only one place.
1057
 */
1058
static inline int
1059
sosend_space(struct socket *so, int flags)
1060
{
1061
	long space;
1062
1063
	space = sbspace(&so->so_snd);
1064
	if (flags & MSG_OOB)
1065
		space += 1024;
1066
	return (space);
1067
}
1068
1052
int
1069
int
1053
sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio,
1070
sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio,
1054
    struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
1071
    struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
Lines 1061-1066 Link Here
1061
	KASSERT(so->so_proto->pr_flags & PR_ATOMIC,
1078
	KASSERT(so->so_proto->pr_flags & PR_ATOMIC,
1062
	    ("sosend_dgram: !PR_ATOMIC"));
1079
	    ("sosend_dgram: !PR_ATOMIC"));
1063
1080
1081
	if (so->so_proto->pr_usrreqs->pru_finalizecontrol &&
1082
	    (error = (*so->so_proto->pr_usrreqs->pru_finalizecontrol)(so,
1083
	        flags, &control, td)))
1084
		goto out;
1085
1064
	if (uio != NULL)
1086
	if (uio != NULL)
1065
		resid = uio->uio_resid;
1087
		resid = uio->uio_resid;
1066
	else
1088
	else
Lines 1081-1088 Link Here
1081
	    (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0;
1103
	    (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0;
1082
	if (td != NULL)
1104
	if (td != NULL)
1083
		td->td_ru.ru_msgsnd++;
1105
		td->td_ru.ru_msgsnd++;
1106
	/*
1107
	 * NB: Original user supplied control message may have
1108
	 * fit and we may have made it too big when we finalized
1109
	 * it, which will have us return EMSGSIZE below.  This
1110
	 * seems rude, but it is at least functional: the user
1111
	 * can try sending smaller control values (mainly, fewer
1112
	 * fd's at a time, as those are the ones that expand to
1113
	 * twice their size on I32LP64 systems).
1114
	 */
1084
	if (control != NULL)
1115
	if (control != NULL)
1085
		clen = control->m_len;
1116
		clen = m_length(control, NULL);
1086
1117
1087
	SOCKBUF_LOCK(&so->so_snd);
1118
	SOCKBUF_LOCK(&so->so_snd);
1088
	if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
1119
	if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
Lines 1120-1134 Link Here
1120
		}
1151
		}
1121
	}
1152
	}
1122
1153
1123
	/*
1154
	space = sosend_space(so, flags);
1124
	 * Do we need MSG_OOB support in SOCK_DGRAM?  Signs here may be a
1155
	SOCKBUF_UNLOCK(&so->so_snd);
1125
	 * problem and need fixing.
1156
	if (clen > space) {
1126
	 */
1157
		error = EMSGSIZE;
1127
	space = sbspace(&so->so_snd);
1158
		goto out;
1128
	if (flags & MSG_OOB)
1159
	}
1129
		space += 1024;
1130
	space -= clen;
1160
	space -= clen;
1131
	SOCKBUF_UNLOCK(&so->so_snd);
1132
	if (resid > space) {
1161
	if (resid > space) {
1133
		error = EMSGSIZE;
1162
		error = EMSGSIZE;
1134
		goto out;
1163
		goto out;
Lines 1223-1228 Link Here
1223
	int clen = 0, error, dontroute;
1252
	int clen = 0, error, dontroute;
1224
	int atomic = sosendallatonce(so) || top;
1253
	int atomic = sosendallatonce(so) || top;
1225
1254
1255
	if (so->so_proto->pr_usrreqs->pru_finalizecontrol &&
1256
	    (error = (*so->so_proto->pr_usrreqs->pru_finalizecontrol)(so,
1257
	        flags, &control, td)))
1258
		goto out;
1259
1226
	if (uio != NULL)
1260
	if (uio != NULL)
1227
		resid = uio->uio_resid;
1261
		resid = uio->uio_resid;
1228
	else
1262
	else
Lines 1248-1254 Link Here
1248
	if (td != NULL)
1282
	if (td != NULL)
1249
		td->td_ru.ru_msgsnd++;
1283
		td->td_ru.ru_msgsnd++;
1250
	if (control != NULL)
1284
	if (control != NULL)
1251
		clen = control->m_len;
1285
		clen = m_length(control, NULL);
1252
1286
1253
	error = sblock(&so->so_snd, SBLOCKWAIT(flags));
1287
	error = sblock(&so->so_snd, SBLOCKWAIT(flags));
1254
	if (error)
1288
	if (error)
Lines 1292-1300 Link Here
1292
				goto release;
1326
				goto release;
1293
			}
1327
			}
1294
		}
1328
		}
1295
		space = sbspace(&so->so_snd);
1329
		space = sosend_space(so, flags);
1296
		if (flags & MSG_OOB)
1330
		/* NB: control msg is implicitly atomic */
1297
			space += 1024;
1298
		if ((atomic && resid > so->so_snd.sb_hiwat) ||
1331
		if ((atomic && resid > so->so_snd.sb_hiwat) ||
1299
		    clen > so->so_snd.sb_hiwat) {
1332
		    clen > so->so_snd.sb_hiwat) {
1300
			SOCKBUF_UNLOCK(&so->so_snd);
1333
			SOCKBUF_UNLOCK(&so->so_snd);
Lines 1315-1320 Link Here
1315
			goto restart;
1348
			goto restart;
1316
		}
1349
		}
1317
		SOCKBUF_UNLOCK(&so->so_snd);
1350
		SOCKBUF_UNLOCK(&so->so_snd);
1351
		if (clen > space) {
1352
			error = EMSGSIZE;
1353
			goto release;
1354
		}
1318
		space -= clen;
1355
		space -= clen;
1319
		do {
1356
		do {
1320
			if (uio == NULL) {
1357
			if (uio == NULL) {
(-)sys/kern/uipc_usrreq.c (-149 / +288 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 800-805 Link Here
800
}
800
}
801
801
802
static int
802
static int
803
uipc_finalizecontrol(struct socket *so, int flags, struct mbuf **pcontrol,
804
    struct thread *td)
805
{
806
	struct unpcb *unp, *unp2;
807
	int error = 0;
808
	bool wantcred, oneshot;
809
810
	unp = sotounpcb(so);
811
	KASSERT(unp != NULL, ("uipc_finalizecontrol: unp == NULL"));
812
813
	if (*pcontrol != NULL && (error = unp_internalize(pcontrol, td)))
814
		return (error);
815
816
	UNP_LINK_RLOCK();
817
	unp2 = unp->unp_conn;
818
	UNP_LINK_RUNLOCK();
819
820
	/*
821
	 * If not connected, we're done now (might be auto-connect
822
	 * on send, leave everything to caller).  Otherwise, handle
823
	 * one-shot credentials on stream and seqpacket sockets here.
824
	 *
825
	 * XXX If the send fails, we never get another chance.
826
	 * We could restore UNP_WANTCRED if the unp_addsockcred()
827
	 * call fails here but we can't handle the more likely
828
	 * entire-send-fails case.  Deferring clearing the flag
829
	 * is not a great solution either.  Perhaps best would be
830
	 * to have an additional UNP_CREDS_SENT_SUCCESSFULLY flag
831
	 * and check that here.  For now, just leave it this way.
832
	 */
833
	if (unp2 == NULL)
834
		return (0);
835
836
	oneshot = so->so_type == SOCK_SEQPACKET ||
837
	    so->so_type == SOCK_STREAM;
838
	if (oneshot) {
839
		UNP_PCB_LOCK(unp2);
840
		wantcred = (unp2->unp_flags & UNP_WANTCRED) != 0;
841
		unp2->unp_flags &= ~UNP_WANTCRED;
842
		UNP_PCB_UNLOCK(unp2);
843
	} else {
844
		wantcred = true;
845
	}
846
847
	if (wantcred)
848
		error = unp_addsockcred(pcontrol, td);
849
850
	return (error);
851
}
852
853
static int
803
uipc_rcvd(struct socket *so, int flags)
854
uipc_rcvd(struct socket *so, int flags)
804
{
855
{
805
	struct unpcb *unp, *unp2;
856
	struct unpcb *unp, *unp2;
Lines 868-875 Link Here
868
		error = EOPNOTSUPP;
919
		error = EOPNOTSUPP;
869
		goto release;
920
		goto release;
870
	}
921
	}
871
	if (control != NULL && (error = unp_internalize(&control, td)))
872
		goto release;
873
	if ((nam != NULL) || (flags & PRUS_EOF))
922
	if ((nam != NULL) || (flags & PRUS_EOF))
874
		UNP_LINK_WLOCK();
923
		UNP_LINK_WLOCK();
875
	else
924
	else
Lines 903-911 Link Here
903
			error = ENOTCONN;
952
			error = ENOTCONN;
904
			break;
953
			break;
905
		}
954
		}
906
		/* Lockless read. */
907
		if (unp2->unp_flags & UNP_WANTCRED)
908
			control = unp_addsockcred(td, control);
909
		UNP_PCB_LOCK(unp);
955
		UNP_PCB_LOCK(unp);
910
		if (unp->unp_addr != NULL)
956
		if (unp->unp_addr != NULL)
911
			from = (struct sockaddr *)unp->unp_addr;
957
			from = (struct sockaddr *)unp->unp_addr;
Lines 973-986 Link Here
973
		so2 = unp2->unp_socket;
1019
		so2 = unp2->unp_socket;
974
		UNP_PCB_LOCK(unp2);
1020
		UNP_PCB_LOCK(unp2);
975
		SOCKBUF_LOCK(&so2->so_rcv);
1021
		SOCKBUF_LOCK(&so2->so_rcv);
976
		if (unp2->unp_flags & UNP_WANTCRED) {
977
			/*
978
			 * Credentials are passed only once on SOCK_STREAM
979
			 * and SOCK_SEQPACKET.
980
			 */
981
			unp2->unp_flags &= ~UNP_WANTCRED;
982
			control = unp_addsockcred(td, control);
983
		}
984
		/*
1022
		/*
985
		 * Send to paired receive port, and then reduce send buffer
1023
		 * Send to paired receive port, and then reduce send buffer
986
		 * hiwater marks to maintain backpressure.  Wake up readers.
1024
		 * hiwater marks to maintain backpressure.  Wake up readers.
Lines 988-996 Link Here
988
		switch (so->so_type) {
1026
		switch (so->so_type) {
989
		case SOCK_STREAM:
1027
		case SOCK_STREAM:
990
			if (control != NULL) {
1028
			if (control != NULL) {
991
				if (sbappendcontrol_locked(&so2->so_rcv, m,
1029
				sbappendcontrol_locked(&so2->so_rcv, m,
992
				    control))
1030
				    control);
993
					control = NULL;
1031
				control = NULL;
994
			} else
1032
			} else
995
				sbappend_locked(&so2->so_rcv, m, flags);
1033
				sbappend_locked(&so2->so_rcv, m, flags);
996
			break;
1034
			break;
Lines 1011-1016 Link Here
1011
			break;
1049
			break;
1012
			}
1050
			}
1013
		}
1051
		}
1052
		m = NULL;
1014
1053
1015
		mbcnt = so2->so_rcv.sb_mbcnt;
1054
		mbcnt = so2->so_rcv.sb_mbcnt;
1016
		sbcc = sbavail(&so2->so_rcv);
1055
		sbcc = sbavail(&so2->so_rcv);
Lines 1031-1037 Link Here
1031
			so->so_snd.sb_flags |= SB_STOP;
1070
			so->so_snd.sb_flags |= SB_STOP;
1032
		SOCKBUF_UNLOCK(&so->so_snd);
1071
		SOCKBUF_UNLOCK(&so->so_snd);
1033
		UNP_PCB_UNLOCK(unp2);
1072
		UNP_PCB_UNLOCK(unp2);
1034
		m = NULL;
1035
		break;
1073
		break;
1036
	}
1074
	}
1037
1075
Lines 1164-1169 Link Here
1164
	.pru_disconnect =	uipc_disconnect,
1202
	.pru_disconnect =	uipc_disconnect,
1165
	.pru_listen =		uipc_listen,
1203
	.pru_listen =		uipc_listen,
1166
	.pru_peeraddr =		uipc_peeraddr,
1204
	.pru_peeraddr =		uipc_peeraddr,
1205
	.pru_finalizecontrol =	uipc_finalizecontrol,
1167
	.pru_rcvd =		uipc_rcvd,
1206
	.pru_rcvd =		uipc_rcvd,
1168
	.pru_send =		uipc_send,
1207
	.pru_send =		uipc_send,
1169
	.pru_sense =		uipc_sense,
1208
	.pru_sense =		uipc_sense,
Lines 1186-1191 Link Here
1186
	.pru_disconnect =	uipc_disconnect,
1225
	.pru_disconnect =	uipc_disconnect,
1187
	.pru_listen =		uipc_listen,
1226
	.pru_listen =		uipc_listen,
1188
	.pru_peeraddr =		uipc_peeraddr,
1227
	.pru_peeraddr =		uipc_peeraddr,
1228
	.pru_finalizecontrol =	uipc_finalizecontrol,
1189
	.pru_rcvd =		uipc_rcvd,
1229
	.pru_rcvd =		uipc_rcvd,
1190
	.pru_send =		uipc_send,
1230
	.pru_send =		uipc_send,
1191
	.pru_sense =		uipc_sense,
1231
	.pru_sense =		uipc_sense,
Lines 1208-1213 Link Here
1208
	.pru_disconnect =	uipc_disconnect,
1248
	.pru_disconnect =	uipc_disconnect,
1209
	.pru_listen =		uipc_listen,
1249
	.pru_listen =		uipc_listen,
1210
	.pru_peeraddr =		uipc_peeraddr,
1250
	.pru_peeraddr =		uipc_peeraddr,
1251
	.pru_finalizecontrol =	uipc_finalizecontrol,
1211
	.pru_rcvd =		uipc_rcvd,
1252
	.pru_rcvd =		uipc_rcvd,
1212
	.pru_send =		uipc_send,
1253
	.pru_send =		uipc_send,
1213
	.pru_ready =		uipc_ready,
1254
	.pru_ready =		uipc_ready,
Lines 1808-1814 Link Here
1808
			    SCM_RIGHTS, SOL_SOCKET);
1849
			    SCM_RIGHTS, SOL_SOCKET);
1809
			if (*controlp == NULL) {
1850
			if (*controlp == NULL) {
1810
				FILEDESC_XUNLOCK(fdesc);
1851
				FILEDESC_XUNLOCK(fdesc);
1811
				error = E2BIG;
1852
				error = ENOBUFS;
1812
				unp_freerights(fdep, newfds);
1853
				unp_freerights(fdep, newfds);
1813
				goto next;
1854
				goto next;
1814
			}
1855
			}
Lines 1896-2057 Link Here
1896
	UNP_DEFERRED_LOCK_INIT();
1937
	UNP_DEFERRED_LOCK_INIT();
1897
}
1938
}
1898
1939
1940
/*
1941
 * Arguments passed to internalizer/transformer (ix = internal xform).
1942
 * The transformation function may fill in a new ix_mbuf.
1943
 */
1944
struct internalize_transform_data {
1945
	socklen_t	ix_odatalen;	/* original data length in bytes */
1946
	socklen_t	ix_ndatalen;	/* new data length, or 0 */
1947
	void		*ix_odata;	/* original data */
1948
	void 		*ix_ndata;	/* new data area, or NULL */
1949
	struct mbuf	*ix_mbuf;	/* mbuf for new data */
1950
	struct thread	*ix_td;		/* calling thread */
1951
};
1952
1953
/*
1954
 * Internalizers.  If you provide a nonzero size, we pre-allocate
1955
 * the ix_mbuf and you get a nonzero ndatasize and non-NULL ndata.
1956
 */
1957
struct unp_scm_internalize_op {
1958
	socklen_t size;		/* predefined output size, or 0 */
1959
	int	(*func)(struct internalize_transform_data *);
1960
};
1961
1962
static int unp_internalize_creds(struct internalize_transform_data *);
1963
static int unp_internalize_fds(struct internalize_transform_data *);
1964
static int unp_internalize_timestamp(struct internalize_transform_data *);
1965
static int unp_internalize_bintime(struct internalize_transform_data *);
1966
1967
static struct unp_scm_internalize_op unp_internalize_ops[] = {
1968
	[SCM_CREDS] = { sizeof(struct cmsgcred), unp_internalize_creds },
1969
	[SCM_RIGHTS] = { 0, unp_internalize_fds },
1970
	[SCM_TIMESTAMP] = { sizeof(struct timeval), unp_internalize_timestamp },
1971
	[SCM_BINTIME] = { sizeof(struct bintime), unp_internalize_bintime },
1972
};
1973
1974
/*
1975
 * Convert incoming control message from user-supplied format
1976
 * to internal form.
1977
 *
1978
 * Note that when we're called, *controlp is a single mbuf
1979
 * whose m_len is the length of the cmsg data structures
1980
 * that have not yet been internalized.  On return, *controlp
1981
 * is an mbuf chain whose individual mbufs are internalized;
1982
 * this chain may have a different length.
1983
 *
1984
 * Caller will always m_freem(*controlp), even if we return error.
1985
 */
1899
static int
1986
static int
1900
unp_internalize(struct mbuf **controlp, struct thread *td)
1987
unp_internalize(struct mbuf **controlp, struct thread *td)
1901
{
1988
{
1902
	struct mbuf *control = *controlp;
1989
	struct unp_scm_internalize_op *op;
1903
	struct proc *p = td->td_proc;
1990
	struct internalize_transform_data ix;
1904
	struct filedesc *fdesc = p->p_fd;
1991
	struct cmsghdr *cm;
1905
	struct bintime *bt;
1992
	struct mbuf *control, *m;
1906
	struct cmsghdr *cm = mtod(control, struct cmsghdr *);
1993
	void *odata;
1907
	struct cmsgcred *cmcred;
1994
	int cmtype, error;
1908
	struct filedescent *fde, **fdep, *fdev;
1995
	socklen_t clen, size, odatalen;
1909
	struct file *fp;
1910
	struct timeval *tv;
1911
	int i, *fdp;
1912
	void *data;
1913
	socklen_t clen = control->m_len, datalen;
1914
	int error, oldfds;
1915
	u_int newlen;
1916
1996
1917
	UNP_LINK_UNLOCK_ASSERT();
1997
	UNP_LINK_UNLOCK_ASSERT();
1918
1998
1999
	ix.ix_td = td;		/* never changes, just passed through */
2000
1919
	error = 0;
2001
	error = 0;
2002
	control = *controlp;
1920
	*controlp = NULL;
2003
	*controlp = NULL;
1921
	while (cm != NULL) {
2004
	clen = control->m_len;
1922
		if (sizeof(*cm) > clen || cm->cmsg_level != SOL_SOCKET
2005
	cm = mtod(control, struct cmsghdr *);
1923
		    || cm->cmsg_len > clen || cm->cmsg_len < sizeof(*cm)) {
1924
			error = EINVAL;
1925
			goto out;
1926
		}
1927
		data = CMSG_DATA(cm);
1928
		datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1929
2006
1930
		switch (cm->cmsg_type) {
2007
	while (error == 0) {
1931
		/*
2008
		/*
1932
		 * Fill in credential information.
2009
		 * Verify current control message, and set up type
2010
		 * and old data pointer and size values.
1933
		 */
2011
		 */
1934
		case SCM_CREDS:
2012
		if (clen < sizeof(*cm) || cm->cmsg_level != SOL_SOCKET ||
1935
			*controlp = sbcreatecontrol(NULL, sizeof(*cmcred),
2013
		    cm->cmsg_len > clen || cm->cmsg_len < sizeof(*cm)) {
1936
			    SCM_CREDS, SOL_SOCKET);
2014
			error = EINVAL;
1937
			if (*controlp == NULL) {
1938
				error = ENOBUFS;
1939
				goto out;
1940
			}
1941
			cmcred = (struct cmsgcred *)
1942
			    CMSG_DATA(mtod(*controlp, struct cmsghdr *));
1943
			cmcred->cmcred_pid = p->p_pid;
1944
			cmcred->cmcred_uid = td->td_ucred->cr_ruid;
1945
			cmcred->cmcred_gid = td->td_ucred->cr_rgid;
1946
			cmcred->cmcred_euid = td->td_ucred->cr_uid;
1947
			cmcred->cmcred_ngroups = MIN(td->td_ucred->cr_ngroups,
1948
			    CMGROUP_MAX);
1949
			for (i = 0; i < cmcred->cmcred_ngroups; i++)
1950
				cmcred->cmcred_groups[i] =
1951
				    td->td_ucred->cr_groups[i];
1952
			break;
2015
			break;
2016
		}
1953
2017
1954
		case SCM_RIGHTS:
2018
		cmtype = cm->cmsg_type;
1955
			oldfds = datalen / sizeof (int);
2019
		if (cmtype < 0 || cmtype >= nitems(unp_internalize_ops)) {
1956
			if (oldfds == 0)
2020
			error = EINVAL;
1957
				break;
2021
			break;
1958
			/*
2022
		}
1959
			 * Check that all the FDs passed in refer to legal
2023
		op = &unp_internalize_ops[cmtype];
1960
			 * files.  If not, reject the entire operation.
2024
		if (op->func == NULL) {
1961
			 */
2025
			error = EINVAL;
1962
			fdp = data;
2026
			break;
1963
			FILEDESC_SLOCK(fdesc);
2027
		}
1964
			for (i = 0; i < oldfds; i++, fdp++) {
1965
				fp = fget_locked(fdesc, *fdp);
1966
				if (fp == NULL) {
1967
					FILEDESC_SUNLOCK(fdesc);
1968
					error = EBADF;
1969
					goto out;
1970
				}
1971
				if (!(fp->f_ops->fo_flags & DFLAG_PASSABLE)) {
1972
					FILEDESC_SUNLOCK(fdesc);
1973
					error = EOPNOTSUPP;
1974
					goto out;
1975
				}
1976
2028
1977
			}
2029
		odata = CMSG_DATA(cm);
2030
		odatalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)odata;
1978
2031
1979
			/*
2032
		ix.ix_odata = odata;
1980
			 * Now replace the integer FDs with pointers to the
2033
		ix.ix_odatalen = odatalen;
1981
			 * file structure and capability rights.
1982
			 */
1983
			newlen = oldfds * sizeof(fdep[0]);
1984
			*controlp = sbcreatecontrol(NULL, newlen,
1985
			    SCM_RIGHTS, SOL_SOCKET);
1986
			if (*controlp == NULL) {
1987
				FILEDESC_SUNLOCK(fdesc);
1988
				error = E2BIG;
1989
				goto out;
1990
			}
1991
			fdp = data;
1992
			fdep = (struct filedescent **)
1993
			    CMSG_DATA(mtod(*controlp, struct cmsghdr *));
1994
			fdev = malloc(sizeof(*fdev) * oldfds, M_FILECAPS,
1995
			    M_WAITOK);
1996
			for (i = 0; i < oldfds; i++, fdev++, fdp++) {
1997
				fde = &fdesc->fd_ofiles[*fdp];
1998
				fdep[i] = fdev;
1999
				fdep[i]->fde_file = fde->fde_file;
2000
				filecaps_copy(&fde->fde_caps,
2001
				    &fdep[i]->fde_caps, true);
2002
				unp_internalize_fp(fdep[i]->fde_file);
2003
			}
2004
			FILEDESC_SUNLOCK(fdesc);
2005
			break;
2006
2034
2007
		case SCM_TIMESTAMP:
2035
		/*
2008
			*controlp = sbcreatecontrol(NULL, sizeof(*tv),
2036
		 * If transform function gives us a fixed data
2009
			    SCM_TIMESTAMP, SOL_SOCKET);
2037
		 * size, allocate new mbuf here, else leave it
2010
			if (*controlp == NULL) {
2038
		 * to the function.
2039
		 */
2040
		if ((size = op->size) != 0) {
2041
			m = sbcreatecontrol(NULL, size, cmtype, SOL_SOCKET);
2042
			if (m == NULL) {
2011
				error = ENOBUFS;
2043
				error = ENOBUFS;
2012
				goto out;
2044
				break;
2013
			}
2045
			}
2014
			tv = (struct timeval *)
2046
			ix.ix_mbuf = m;
2015
			    CMSG_DATA(mtod(*controlp, struct cmsghdr *));
2047
			ix.ix_ndata = CMSG_DATA(mtod(m, struct cmsghdr *));
2016
			microtime(tv);
2048
			ix.ix_ndatalen = size;
2017
			break;
2049
		} else {
2050
			ix.ix_mbuf = NULL;
2051
			ix.ix_ndata = NULL;
2052
			ix.ix_ndatalen = 0;
2053
		}
2018
2054
2019
		case SCM_BINTIME:
2055
		/*
2020
			*controlp = sbcreatecontrol(NULL, sizeof(*bt),
2056
		 * Apply transform and append new mbuf (if any) to
2021
			    SCM_BINTIME, SOL_SOCKET);
2057
		 * new control chain, even on error, so that it
2022
			if (*controlp == NULL) {
2058
		 * will get freed.
2023
				error = ENOBUFS;
2059
		 */
2024
				goto out;
2060
		error = (*op->func)(&ix);
2025
			}
2061
		if ((m = ix.ix_mbuf) != NULL) {
2026
			bt = (struct bintime *)
2062
			*controlp = m;
2027
			    CMSG_DATA(mtod(*controlp, struct cmsghdr *));
2063
			controlp = &m->m_next;
2028
			bintime(bt);
2029
			break;
2030
2031
		default:
2032
			error = EINVAL;
2033
			goto out;
2034
		}
2064
		}
2035
2065
2036
		controlp = &(*controlp)->m_next;
2066
		/* Advance to next message. */
2037
		if (CMSG_SPACE(datalen) < clen) {
2067
		size = CMSG_SPACE(odatalen);
2038
			clen -= CMSG_SPACE(datalen);
2068
		if (size >= clen)
2039
			cm = (struct cmsghdr *)
2069
			break;
2040
			    ((caddr_t)cm + CMSG_SPACE(datalen));
2070
		cm = (struct cmsghdr *)((caddr_t)cm + size);
2041
		} else {
2071
		clen -= size;
2042
			clen = 0;
2043
			cm = NULL;
2044
		}
2045
	}
2072
	}
2046
2073
2047
out:
2048
	m_freem(control);
2074
	m_freem(control);
2049
	return (error);
2075
	return (error);
2050
}
2076
}
2051
2077
2052
static struct mbuf *
2078
/*
2053
unp_addsockcred(struct thread *td, struct mbuf *control)
2079
 * Internalize file descriptors ("rights").
2080
 */
2081
static int
2082
unp_internalize_fds(struct internalize_transform_data *ix)
2054
{
2083
{
2084
	struct proc *p = ix->ix_td->td_proc;
2085
	struct filedesc *fdesc = p->p_fd;
2086
	struct filedescent *fde, **fdep, *fdev;
2087
	struct file *fp;
2088
	struct mbuf *m;
2089
	int i, *fdp;
2090
	int oldfds;
2091
	u_int newlen;
2092
2093
	KASSERT(ix->ix_ndatalen == 0, ("%s: datalen", __func__));
2094
2095
	/* Round down: this is forgiving, if slightly wrong. */
2096
	oldfds = ix->ix_odatalen / sizeof (int);
2097
	if (oldfds == 0)
2098
		return (0);
2099
2100
	/*
2101
	 * Check that all the FDs passed in refer to legal
2102
	 * files.  If not, reject the entire operation.
2103
	 */
2104
	fdp = ix->ix_odata;
2105
	FILEDESC_SLOCK(fdesc);
2106
	for (i = 0; i < oldfds; i++, fdp++) {
2107
		fp = fget_locked(fdesc, *fdp);
2108
		if (fp == NULL) {
2109
			FILEDESC_SUNLOCK(fdesc);
2110
			return (EBADF);
2111
		}
2112
		if (!(fp->f_ops->fo_flags & DFLAG_PASSABLE)) {
2113
			FILEDESC_SUNLOCK(fdesc);
2114
			return (EOPNOTSUPP);
2115
		}
2116
2117
	}
2118
2119
	/*
2120
	 * Now replace the integer FDs with pointers to the
2121
	 * file structure and capability rights.
2122
	 */
2123
	newlen = oldfds * sizeof(fdep[0]);
2124
	m = sbcreatecontrol(NULL, newlen, SCM_RIGHTS, SOL_SOCKET);
2125
	if (m == NULL) {
2126
		FILEDESC_SUNLOCK(fdesc);
2127
		return (ENOBUFS);
2128
	}
2129
2130
	fdp = ix->ix_odata;
2131
	fdep = (struct filedescent **)CMSG_DATA(mtod(m, struct cmsghdr *));
2132
	fdev = malloc(sizeof(*fdev) * oldfds, M_FILECAPS, M_WAITOK);
2133
	for (i = 0; i < oldfds; i++, fdev++, fdp++) {
2134
		fde = &fdesc->fd_ofiles[*fdp];
2135
		fdep[i] = fdev;
2136
		fdep[i]->fde_file = fde->fde_file;
2137
		filecaps_copy(&fde->fde_caps, &fdep[i]->fde_caps, true);
2138
		unp_internalize_fp(fdep[i]->fde_file);
2139
	}
2140
	FILEDESC_SUNLOCK(fdesc);
2141
2142
	ix->ix_mbuf = m;
2143
	return (0);
2144
}
2145
2146
static int
2147
unp_internalize_creds(struct internalize_transform_data *ix)
2148
{
2149
	struct cmsgcred *cmcred;
2150
	int i, ngroups;
2151
	struct thread *td = ix->ix_td;
2152
	struct ucred *cr = td->td_ucred;
2153
2154
	KASSERT(ix->ix_ndatalen == sizeof(*cmcred), ("%s: datalen", __func__));
2155
	cmcred = ix->ix_ndata;
2156
	cmcred->cmcred_pid = td->td_proc->p_pid;
2157
	cmcred->cmcred_uid = cr->cr_ruid;
2158
	cmcred->cmcred_gid = cr->cr_rgid;
2159
	cmcred->cmcred_euid = cr->cr_uid;
2160
	ngroups = MIN(cr->cr_ngroups, CMGROUP_MAX);
2161
	cmcred->cmcred_ngroups = ngroups;
2162
	for (i = 0; i < ngroups; i++)
2163
		cmcred->cmcred_groups[i] = cr->cr_groups[i];
2164
	return (0);
2165
}
2166
2167
static int
2168
unp_internalize_timestamp(struct internalize_transform_data *ix)
2169
{
2170
	struct timeval *tv;
2171
2172
	KASSERT(ix->ix_ndatalen == sizeof(*tv), ("%s: datalen", __func__));
2173
	tv = ix->ix_ndata;
2174
	microtime(tv);
2175
	return (0);
2176
}
2177
2178
static int
2179
unp_internalize_bintime(struct internalize_transform_data *ix)
2180
{
2181
	struct bintime *bt;
2182
2183
	KASSERT(ix->ix_ndatalen == sizeof(*bt), ("%s: datalen", __func__));
2184
	bt = ix->ix_ndata;
2185
	bintime(bt);
2186
	return (0);
2187
}
2188
2189
static int
2190
unp_addsockcred(struct mbuf **pcontrol, struct thread *td)
2191
{
2192
	struct mbuf *control = *pcontrol;
2055
	struct mbuf *m, *n, *n_prev;
2193
	struct mbuf *m, *n, *n_prev;
2056
	struct sockcred *sc;
2194
	struct sockcred *sc;
2057
	const struct cmsghdr *cm;
2195
	const struct cmsghdr *cm;
Lines 2061-2067 Link Here
2061
	ngroups = MIN(td->td_ucred->cr_ngroups, CMGROUP_MAX);
2199
	ngroups = MIN(td->td_ucred->cr_ngroups, CMGROUP_MAX);
2062
	m = sbcreatecontrol(NULL, SOCKCREDSIZE(ngroups), SCM_CREDS, SOL_SOCKET);
2200
	m = sbcreatecontrol(NULL, SOCKCREDSIZE(ngroups), SCM_CREDS, SOL_SOCKET);
2063
	if (m == NULL)
2201
	if (m == NULL)
2064
		return (control);
2202
		return (ENOBUFS);
2065
2203
2066
	sc = (struct sockcred *) CMSG_DATA(mtod(m, struct cmsghdr *));
2204
	sc = (struct sockcred *) CMSG_DATA(mtod(m, struct cmsghdr *));
2067
	sc->sc_uid = td->td_ucred->cr_ruid;
2205
	sc->sc_uid = td->td_ucred->cr_ruid;
Lines 2095-2101 Link Here
2095
2233
2096
	/* Prepend it to the head. */
2234
	/* Prepend it to the head. */
2097
	m->m_next = control;
2235
	m->m_next = control;
2098
	return (m);
2236
	*pcontrol = m;
2237
	return (0);
2099
}
2238
}
2100
2239
2101
static struct unpcb *
2240
static struct unpcb *
(-)sys/sys/protosw.h (+2 lines)
Lines 199-204 Link Here
199
	int	(*pru_listen)(struct socket *so, int backlog,
199
	int	(*pru_listen)(struct socket *so, int backlog,
200
		    struct thread *td);
200
		    struct thread *td);
201
	int	(*pru_peeraddr)(struct socket *so, struct sockaddr **nam);
201
	int	(*pru_peeraddr)(struct socket *so, struct sockaddr **nam);
202
	int	(*pru_finalizecontrol)(struct socket *so, int flags, struct mbuf **pcontrol,
203
		    struct thread *td);
202
	int	(*pru_rcvd)(struct socket *so, int flags);
204
	int	(*pru_rcvd)(struct socket *so, int flags);
203
	int	(*pru_rcvoob)(struct socket *so, struct mbuf *m, int flags);
205
	int	(*pru_rcvoob)(struct socket *so, struct mbuf *m, int flags);
204
	int	(*pru_send)(struct socket *so, int flags, struct mbuf *m,
206
	int	(*pru_send)(struct socket *so, int flags, struct mbuf *m,
(-)sys/sys/sockbuf.h (-2 / +2 lines)
Lines 146-154 Link Here
146
	    struct mbuf *m0, struct mbuf *control);
146
	    struct mbuf *m0, struct mbuf *control);
147
int	sbappendaddr_nospacecheck_locked(struct sockbuf *sb,
147
int	sbappendaddr_nospacecheck_locked(struct sockbuf *sb,
148
	    const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control);
148
	    const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control);
149
int	sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
149
void	sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
150
	    struct mbuf *control);
150
	    struct mbuf *control);
151
int	sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
151
void	sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
152
	    struct mbuf *control);
152
	    struct mbuf *control);
153
void	sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
153
void	sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
154
void	sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
154
void	sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);

Return to bug 181741