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

Collapse All | Expand All

(-)sys/compat/linux/linux_socket.c (-26 / +28 lines)
Lines 1085-1091 linux_sendmsg_common(struct thread *td, l_int s, struc Link Here
1085
    l_uint flags)
1085
    l_uint flags)
1086
{
1086
{
1087
	struct cmsghdr *cmsg;
1087
	struct cmsghdr *cmsg;
1088
	struct cmsgcred cmcred;
1089
	struct mbuf *control;
1088
	struct mbuf *control;
1090
	struct msghdr msg;
1089
	struct msghdr msg;
1091
	struct l_cmsghdr linux_cmsg;
1090
	struct l_cmsghdr linux_cmsg;
Lines 1096-1101 linux_sendmsg_common(struct thread *td, l_int s, struc Link Here
1096
	struct sockaddr *sa;
1095
	struct sockaddr *sa;
1097
	sa_family_t sa_family;
1096
	sa_family_t sa_family;
1098
	void *data;
1097
	void *data;
1098
	l_size_t len;
1099
	int error;
1099
	int error;
1100
1100
1101
	error = copyin(msghdr, &linux_msg, sizeof(linux_msg));
1101
	error = copyin(msghdr, &linux_msg, sizeof(linux_msg));
Lines 1126-1132 linux_sendmsg_common(struct thread *td, l_int s, struc Link Here
1126
		return (error);
1126
		return (error);
1127
1127
1128
	control = NULL;
1128
	control = NULL;
1129
	cmsg = NULL;
1130
1129
1131
	if ((ptr_cmsg = LINUX_CMSG_FIRSTHDR(&linux_msg)) != NULL) {
1130
	if ((ptr_cmsg = LINUX_CMSG_FIRSTHDR(&linux_msg)) != NULL) {
1132
		error = kern_getsockname(td, s, &sa, &datalen);
1131
		error = kern_getsockname(td, s, &sa, &datalen);
Lines 1136-1143 linux_sendmsg_common(struct thread *td, l_int s, struc Link Here
1136
		free(sa, M_SONAME);
1135
		free(sa, M_SONAME);
1137
1136
1138
		error = ENOBUFS;
1137
		error = ENOBUFS;
1139
		cmsg = malloc(CMSG_HDRSZ, M_LINUX, M_WAITOK|M_ZERO);
1140
		control = m_get(M_WAITOK, MT_CONTROL);
1138
		control = m_get(M_WAITOK, MT_CONTROL);
1139
		MCLGET(control, M_WAITOK);
1140
		data = mtod(control, void *);
1141
		datalen = 0;
1141
1142
1142
		do {
1143
		do {
1143
			error = copyin(ptr_cmsg, &linux_cmsg,
1144
			error = copyin(ptr_cmsg, &linux_cmsg,
Lines 1149-1158 linux_sendmsg_common(struct thread *td, l_int s, struc Link Here
1149
			if (linux_cmsg.cmsg_len < sizeof(struct l_cmsghdr))
1150
			if (linux_cmsg.cmsg_len < sizeof(struct l_cmsghdr))
1150
				goto bad;
1151
				goto bad;
1151
1152
1153
			if (datalen + CMSG_HDRSZ > MCLBYTES)
1154
				goto bad;
1155
1152
			/*
1156
			/*
1153
			 * Now we support only SCM_RIGHTS and SCM_CRED,
1157
			 * Now we support only SCM_RIGHTS and SCM_CRED,
1154
			 * so return EINVAL in any other cmsg_type
1158
			 * so return EINVAL in any other cmsg_type
1155
			 */
1159
			 */
1160
			cmsg = data;
1156
			cmsg->cmsg_type =
1161
			cmsg->cmsg_type =
1157
			    linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type);
1162
			    linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type);
1158
			cmsg->cmsg_level =
1163
			cmsg->cmsg_level =
Lines 1170-1204 linux_sendmsg_common(struct thread *td, l_int s, struc Link Here
1170
			if (sa_family != AF_UNIX)
1175
			if (sa_family != AF_UNIX)
1171
				continue;
1176
				continue;
1172
1177
1173
			data = LINUX_CMSG_DATA(ptr_cmsg);
1178
			if (cmsg->cmsg_type == SCM_CREDS) {
1174
			datalen = linux_cmsg.cmsg_len - L_CMSG_HDRSZ;
1179
				len = sizeof(struct cmsgcred);
1180
				if (datalen + CMSG_SPACE(len) > MCLBYTES)
1181
					goto bad;
1175
1182
1176
			switch (cmsg->cmsg_type)
1177
			{
1178
			case SCM_RIGHTS:
1179
				break;
1180
1181
			case SCM_CREDS:
1182
				data = &cmcred;
1183
				datalen = sizeof(cmcred);
1184
1185
				/*
1183
				/*
1186
				 * The lower levels will fill in the structure
1184
				 * The lower levels will fill in the structure
1187
				 */
1185
				 */
1188
				bzero(data, datalen);
1186
				memset(CMSG_DATA(data), 0, len);
1189
				break;
1187
			} else {
1188
				len = linux_cmsg.cmsg_len - L_CMSG_HDRSZ;
1189
				if (datalen + CMSG_SPACE(len) < datalen ||
1190
				    datalen + CMSG_SPACE(len) > MCLBYTES)
1191
					goto bad;
1192
1193
				error = copyin(LINUX_CMSG_DATA(ptr_cmsg),
1194
				    CMSG_DATA(data), len);
1195
				if (error != 0)
1196
					goto bad;
1190
			}
1197
			}
1191
1198
1192
			cmsg->cmsg_len = CMSG_LEN(datalen);
1199
			cmsg->cmsg_len = CMSG_LEN(len);
1193
1200
			data = (char *)data + CMSG_SPACE(len);
1194
			error = ENOBUFS;
1201
			datalen += CMSG_SPACE(len);
1195
			if (!m_append(control, CMSG_HDRSZ, (c_caddr_t)cmsg))
1196
				goto bad;
1197
			if (!m_append(control, datalen, (c_caddr_t)data))
1198
				goto bad;
1199
		} while ((ptr_cmsg = LINUX_CMSG_NXTHDR(&linux_msg, ptr_cmsg)));
1202
		} while ((ptr_cmsg = LINUX_CMSG_NXTHDR(&linux_msg, ptr_cmsg)));
1200
1203
1201
		if (m_length(control, NULL) == 0) {
1204
		control->m_len = datalen;
1205
		if (datalen == 0) {
1202
			m_freem(control);
1206
			m_freem(control);
1203
			control = NULL;
1207
			control = NULL;
1204
		}
1208
		}
Lines 1212-1219 linux_sendmsg_common(struct thread *td, l_int s, struc Link Here
1212
bad:
1216
bad:
1213
	m_freem(control);
1217
	m_freem(control);
1214
	free(iov, M_IOV);
1218
	free(iov, M_IOV);
1215
	if (cmsg)
1216
		free(cmsg, M_LINUX);
1217
	return (error);
1219
	return (error);
1218
}
1220
}
1219
1221

Return to bug 217901