summaryrefslogtreecommitdiff
path: root/Kernel/Syscalls
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-08-21 16:45:42 +0200
committerAndreas Kling <kling@serenityos.org>2022-08-21 16:45:42 +0200
commit42435ce5e475c355330f3cb16d2334a339588cb9 (patch)
tree2aaadda6ea84fda3e4b5d76a5dd24bf3e1369d12 /Kernel/Syscalls
parent8997c6a4d1f1047e53d640982568e1e45ed8f171 (diff)
downloadserenity-42435ce5e475c355330f3cb16d2334a339588cb9.zip
Kernel: Make sys$recvfrom() with MSG_DONTWAIT not so racy
Instead of temporary changing the open file description's "blocking" flag while doing a non-waiting recvfrom, we instead plumb the currently wanted blocking behavior all the way through to the underlying socket.
Diffstat (limited to 'Kernel/Syscalls')
-rw-r--r--Kernel/Syscalls/socket.cpp9
1 files changed, 2 insertions, 7 deletions
diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp
index 70eded6dc4..d7e292011f 100644
--- a/Kernel/Syscalls/socket.cpp
+++ b/Kernel/Syscalls/socket.cpp
@@ -241,15 +241,10 @@ ErrorOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user
if (socket.is_shut_down_for_reading())
return 0;
- bool original_blocking = description->is_blocking();
- if (flags & MSG_DONTWAIT)
- description->set_blocking(false);
-
auto data_buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len));
Time timestamp {};
- auto result = socket.recvfrom(*description, data_buffer, iovs[0].iov_len, flags, user_addr, user_addr_length, timestamp);
- if (flags & MSG_DONTWAIT)
- description->set_blocking(original_blocking);
+ bool blocking = (flags & MSG_DONTWAIT) ? false : description->is_blocking();
+ auto result = socket.recvfrom(*description, data_buffer, iovs[0].iov_len, flags, user_addr, user_addr_length, timestamp, blocking);
if (result.is_error())
return result.release_error();