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 |
} |