Revision 607175e0
b/linux-user/syscall.c | ||
---|---|---|
44 | 44 |
#include <signal.h> |
45 | 45 |
#include <sched.h> |
46 | 46 |
#include <sys/socket.h> |
47 |
#include <sys/un.h> |
|
47 | 48 |
#include <sys/uio.h> |
48 | 49 |
#include <sys/poll.h> |
49 | 50 |
#include <sys/times.h> |
... | ... | |
735 | 736 |
abi_ulong target_addr, |
736 | 737 |
socklen_t len) |
737 | 738 |
{ |
739 |
const socklen_t unix_maxlen = sizeof (struct sockaddr_un); |
|
740 |
sa_family_t sa_family; |
|
738 | 741 |
struct target_sockaddr *target_saddr; |
739 | 742 |
|
740 | 743 |
target_saddr = lock_user(VERIFY_READ, target_addr, len, 1); |
741 | 744 |
if (!target_saddr) |
742 | 745 |
return -TARGET_EFAULT; |
746 |
|
|
747 |
sa_family = tswap16(target_saddr->sa_family); |
|
748 |
|
|
749 |
/* Oops. The caller might send a incomplete sun_path; sun_path |
|
750 |
* must be terminated by \0 (see the manual page), but |
|
751 |
* unfortunately it is quite common to specify sockaddr_un |
|
752 |
* length as "strlen(x->sun_path)" while it should be |
|
753 |
* "strlen(...) + 1". We'll fix that here if needed. |
|
754 |
* Linux kernel has a similar feature. |
|
755 |
*/ |
|
756 |
|
|
757 |
if (sa_family == AF_UNIX) { |
|
758 |
if (len < unix_maxlen && len > 0) { |
|
759 |
char *cp = (char*)target_saddr; |
|
760 |
|
|
761 |
if ( cp[len-1] && !cp[len] ) |
|
762 |
len++; |
|
763 |
} |
|
764 |
if (len > unix_maxlen) |
|
765 |
len = unix_maxlen; |
|
766 |
} |
|
767 |
|
|
743 | 768 |
memcpy(addr, target_saddr, len); |
744 |
addr->sa_family = tswap16(target_saddr->sa_family);
|
|
769 |
addr->sa_family = sa_family;
|
|
745 | 770 |
unlock_user(target_saddr, target_addr, 0); |
746 | 771 |
|
747 | 772 |
return 0; |
... | ... | |
1195 | 1220 |
if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) |
1196 | 1221 |
return -TARGET_EINVAL; |
1197 | 1222 |
|
1198 |
addr = alloca(addrlen); |
|
1223 |
addr = alloca(addrlen+1);
|
|
1199 | 1224 |
|
1200 | 1225 |
target_to_host_sockaddr(addr, target_addr, addrlen); |
1201 | 1226 |
return get_errno(bind(sockfd, addr, addrlen)); |
Also available in: Unified diff