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

Collapse All | Expand All

(-)work-linux_socket.c (-19 / +54 lines)
Lines 890-900 Link Here
890
	    UIO_USERSPACE));
890
	    UIO_USERSPACE));
891
}
891
}
892
892
893
static int
894
linux_sa_put(struct osockaddr *osa)
895
{
896
	struct osockaddr sa;
897
	int error, bdom;
898
899
	/*
900
	 * Only read/write the osockaddr family part, the rest is
901
	 * not changed.
902
	 */
903
	error = copyin(osa, &sa, sizeof(sa.sa_family));
904
	if (error != 0)
905
		return (error);
906
907
	bdom = bsd_to_linux_domain(sa.sa_family);
908
	if (bdom == -1)
909
		return (EINVAL);
910
911
	sa.sa_family = bdom;
912
	return (copyout(&sa, osa, sizeof(sa.sa_family)));
913
}
914
915
static int
916
old_bsd_to_linux_sockaddr(struct sockaddr *arg)
917
{
918
	struct sockaddr sa;
919
	size_t sa_len = sizeof(struct sockaddr);
920
	int error, bdom;
921
922
	if ((error = copyin(arg, &sa, sa_len)))
923
		return (error);
924
925
	bdom = bsd_to_linux_domain(sa.sa_family);
926
	if (bdom == -1)
927
		return (EAFNOSUPPORT);
928
929
	*(u_short *)&sa = bdom;
930
	return (copyout(&sa, arg, sa_len));
931
}
932
893
int
933
int
894
linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args)
934
linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args)
895
{
935
{
896
	struct l_sockaddr *lsa;
897
	struct sockaddr *sa;
898
	struct msghdr msg;
936
	struct msghdr msg;
899
	struct iovec aiov;
937
	struct iovec aiov;
900
	int error, fromlen;
938
	int error, fromlen;
Lines 906-919 Link Here
906
			return (error);
944
			return (error);
907
		if (fromlen < 0)
945
		if (fromlen < 0)
908
			return (EINVAL);
946
			return (EINVAL);
909
		sa = malloc(fromlen, M_SONAME, M_WAITOK);
947
		msg.msg_namelen = fromlen;
910
	} else {
948
	} else
911
		fromlen = 0;
949
		msg.msg_namelen = 0;
912
		sa = NULL;
913
	}
914
950
915
	msg.msg_name = sa;
951
	msg.msg_name = (struct sockaddr * __restrict)PTRIN(args->from);
916
	msg.msg_namelen = fromlen;
917
	msg.msg_iov = &aiov;
952
	msg.msg_iov = &aiov;
918
	msg.msg_iovlen = 1;
953
	msg.msg_iovlen = 1;
919
	aiov.iov_base = PTRIN(args->buf);
954
	aiov.iov_base = PTRIN(args->buf);
Lines 921-943 Link Here
921
	msg.msg_control = 0;
956
	msg.msg_control = 0;
922
	msg.msg_flags = linux_to_bsd_msg_flags(args->flags);
957
	msg.msg_flags = linux_to_bsd_msg_flags(args->flags);
923
958
924
	error = kern_recvit(td, args->s, &msg, UIO_SYSSPACE, NULL);
959
	error = kern_recvit(td, args->s, &msg, UIO_USERSPACE, NULL);
925
	if (error != 0)
960
	if (error != 0)
926
		goto out;
961
		return (error);
927
962
928
	if (PTRIN(args->from) != NULL) {
963
	if (PTRIN(args->from) != NULL) {
929
		error = bsd_to_linux_sockaddr(sa, &lsa, msg.msg_namelen);
964
		error = old_bsd_to_linux_sockaddr((struct sockaddr *)PTRIN(args->from));
930
		if (error == 0)
965
		if (error != 0)
931
			error = copyout(lsa, PTRIN(args->from),
966
			return (error);
932
			    msg.msg_namelen);
967
933
		free(lsa, M_SONAME);
968
		error = linux_sa_put((struct osockaddr *)
969
		    PTRIN(args->from));
934
	}
970
	}
935
971
936
	if (error == 0 && PTRIN(args->fromlen) != NULL)
972
	if (PTRIN(args->fromlen) != NULL)
937
		error = copyout(&msg.msg_namelen, PTRIN(args->fromlen),
973
		error = copyout(&msg.msg_namelen, PTRIN(args->fromlen),
938
		    sizeof(msg.msg_namelen));
974
		    sizeof(msg.msg_namelen));
939
out:
975
940
	free(sa, M_SONAME);
941
	return (error);
976
	return (error);
942
}
977
}

Return to bug 259380