From 273dbd0916f75f57639a9bdbfcc6d28c275d091a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 13 Oct 2009 07:19:18 +0000 Subject: [PATCH] * The network syscalls now check if you try to pass a non-userland address to them (which you previously could use to easily crash/take over Haiku). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33570 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/fs/socket.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/fs/socket.cpp b/src/system/kernel/fs/socket.cpp index ec0821808b..f8b53b50c1 100644 --- a/src/system/kernel/fs/socket.cpp +++ b/src/system/kernel/fs/socket.cpp @@ -5,6 +5,7 @@ * Distributed under the terms of the MIT License. */ + #include #include @@ -166,7 +167,7 @@ prepare_userland_msghdr(const msghdr* userMessage, msghdr& message, vecsDeleter.SetTo(vecs); if (!IS_USER_ADDRESS(message.msg_iov) - || user_memcpy(vecs, message.msg_iov, + || user_memcpy(vecs, message.msg_iov, message.msg_iovlen * sizeof(iovec)) != B_OK) { return B_BAD_ADDRESS; } @@ -913,6 +914,9 @@ _user_accept(int socket, struct sockaddr *userAddress, ssize_t _user_recv(int socket, void *data, size_t length, int flags) { + if (data == NULL || !IS_USER_ADDRESS(data)) + return B_BAD_ADDRESS; + SyscallRestartWrapper result; return result = common_recv(socket, data, length, flags, false); } @@ -922,6 +926,9 @@ ssize_t _user_recvfrom(int socket, void *data, size_t length, int flags, struct sockaddr *userAddress, socklen_t *_addressLength) { + if (data == NULL || !IS_USER_ADDRESS(data)) + return B_BAD_ADDRESS; + // check parameters socklen_t addressLength = 0; status_t error = prepare_userland_address_result(userAddress, @@ -1010,6 +1017,9 @@ _user_recvmsg(int socket, struct msghdr *userMessage, int flags) ssize_t _user_send(int socket, const void *data, size_t length, int flags) { + if (data == NULL || !IS_USER_ADDRESS(data)) + return B_BAD_ADDRESS; + SyscallRestartWrapper result; return result = common_send(socket, data, length, flags, false); } @@ -1019,8 +1029,11 @@ ssize_t _user_sendto(int socket, const void *data, size_t length, int flags, const struct sockaddr *userAddress, socklen_t addressLength) { -// TODO: If this is a connection-mode socket, the address parameter is -// supposed to be ignored. + if (data == NULL || !IS_USER_ADDRESS(data)) + return B_BAD_ADDRESS; + + // TODO: If this is a connection-mode socket, the address parameter is + // supposed to be ignored. if (userAddress == NULL || addressLength <= 0 || addressLength > MAX_SOCKET_ADDRESS_LENGTH) { return B_BAD_VALUE;