The syscalls that were returning an address always copied back the full
address back to userland, even if the provided buffer was smaller. Fixes a problem with Firefox, which is for some reason providing a buffer smaller than our sockaddr_in. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24948 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c8661c3885
commit
460c990c5d
@ -111,6 +111,24 @@ prepare_userland_address_result(struct sockaddr* userAddress,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
copy_address_to_userland(const void* address, socklen_t addressLength,
|
||||
sockaddr* userAddress, socklen_t userAddressBufferSize,
|
||||
socklen_t* userAddressLength)
|
||||
{
|
||||
// copy address size and address back to userland
|
||||
if (user_memcpy(userAddressLength, &addressLength,
|
||||
sizeof(socklen_t)) != B_OK
|
||||
|| userAddress != NULL
|
||||
&& user_memcpy(userAddress, address,
|
||||
min_c(addressLength, userAddressBufferSize)) != B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
prepare_userland_msghdr(const msghdr* userMessage, msghdr& message,
|
||||
iovec*& userVecs, MemoryDeleter& vecsDeleter, void*& userAddress,
|
||||
@ -835,14 +853,13 @@ _user_accept(int socket, struct sockaddr *userAddress,
|
||||
SyscallRestartWrapper<int> result;
|
||||
|
||||
char address[MAX_SOCKET_ADDRESS_LEN];
|
||||
socklen_t userAddressBufferSize = addressLength;
|
||||
result = common_accept(socket,
|
||||
userAddress != NULL ? (sockaddr*)address : NULL, &addressLength, false);
|
||||
|
||||
// copy address size and address back to userland
|
||||
if (user_memcpy(_addressLength, &addressLength,
|
||||
sizeof(socklen_t)) != B_OK
|
||||
|| userAddress != NULL
|
||||
&& user_memcpy(userAddress, address, addressLength) != B_OK) {
|
||||
if (copy_address_to_userland(address, addressLength, userAddress,
|
||||
userAddressBufferSize, _addressLength) != B_OK) {
|
||||
_user_close(result);
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
@ -874,16 +891,15 @@ _user_recvfrom(int socket, void *data, size_t length, int flags,
|
||||
SyscallRestartWrapper<ssize_t> result;
|
||||
|
||||
char address[MAX_SOCKET_ADDRESS_LEN];
|
||||
socklen_t userAddressBufferSize = addressLength;
|
||||
result = common_recvfrom(socket, data, length, flags,
|
||||
userAddress != NULL ? (sockaddr*)address : NULL, &addressLength, false);
|
||||
if (result < (ssize_t)0)
|
||||
return result;
|
||||
|
||||
// copy address size and address back to userland
|
||||
if (user_memcpy(_addressLength, &addressLength,
|
||||
sizeof(socklen_t)) != B_OK
|
||||
|| userAddress != NULL
|
||||
&& user_memcpy(userAddress, address, addressLength) != B_OK) {
|
||||
if (copy_address_to_userland(address, addressLength, userAddress,
|
||||
userAddressBufferSize, _addressLength) != B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
@ -1103,16 +1119,15 @@ _user_getpeername(int socket, struct sockaddr *userAddress,
|
||||
|
||||
// getpeername()
|
||||
char address[MAX_SOCKET_ADDRESS_LEN];
|
||||
socklen_t userAddressBufferSize = addressLength;
|
||||
error = common_getpeername(socket, (sockaddr*)address, &addressLength,
|
||||
false);
|
||||
if (error != (status_t)B_OK)
|
||||
return error;
|
||||
|
||||
// copy address size and address back to userland
|
||||
if (user_memcpy(_addressLength, &addressLength,
|
||||
sizeof(socklen_t)) != B_OK
|
||||
|| userAddress != NULL
|
||||
&& user_memcpy(userAddress, address, addressLength) != B_OK) {
|
||||
if (copy_address_to_userland(address, addressLength, userAddress,
|
||||
userAddressBufferSize, _addressLength) != B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
@ -1132,18 +1147,17 @@ _user_getsockname(int socket, struct sockaddr *userAddress,
|
||||
if (error != (status_t)B_OK)
|
||||
return error;
|
||||
|
||||
// getsocknam()
|
||||
// getsockname()
|
||||
char address[MAX_SOCKET_ADDRESS_LEN];
|
||||
socklen_t userAddressBufferSize = addressLength;
|
||||
error = common_getsockname(socket, (sockaddr*)address, &addressLength,
|
||||
false);
|
||||
if (error != (status_t)B_OK)
|
||||
return error;
|
||||
|
||||
// copy address size and address back to userland
|
||||
if (user_memcpy(_addressLength, &addressLength,
|
||||
sizeof(socklen_t)) != B_OK
|
||||
|| userAddress != NULL
|
||||
&& user_memcpy(userAddress, address, addressLength) != B_OK) {
|
||||
if (copy_address_to_userland(address, addressLength, userAddress,
|
||||
userAddressBufferSize, _addressLength) != B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user