summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-07-31 15:57:13 -0400
committerIan Moffett <ian@osmora.org>2025-07-31 15:57:13 -0400
commitee8be1476f057aabeaf306d1411b44201f43b11b (patch)
tree8ff6b83cbe349c3b91313af45af528cde54155df
parent075171e3b90115647f3e4af2664488bae64ee4ca (diff)
kernel: socket: Improve control message logic
- Zero new control buffer before usage - Block if the control message queue is empty Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/kern/kern_socket.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/sys/kern/kern_socket.c b/sys/kern/kern_socket.c
index 0673353..58817c5 100644
--- a/sys/kern/kern_socket.c
+++ b/sys/kern/kern_socket.c
@@ -626,7 +626,7 @@ scret_t
sys_recvmsg(struct syscall_args *scargs)
{
struct msghdr *u_msg = (void *)scargs->arg1;
- void *u_control;
+ void *u_control, *control = NULL;
size_t controllen;
struct iovec msg_iov;
struct msghdr msg;
@@ -653,23 +653,36 @@ sys_recvmsg(struct syscall_args *scargs)
controllen = msg.msg_controllen;
/* Allocate a new control field to copy in */
- msg.msg_control = dynalloc(controllen);
+ control = dynalloc(controllen);
+ msg.msg_control = control;
if (msg.msg_control == NULL) {
uio_copyin_clean(&msg_iov, msg.msg_iovlen);
return -ENOMEM;
}
+ memset(msg.msg_control, 0, controllen);
error = copyin(u_control, msg.msg_control, controllen);
if (error < 0) {
retval = error;
goto done;
}
+ /*
+ * Now wait until we get a control
+ * message
+ */
msg.msg_iov = &msg_iov;
- retval = recvmsg(socket, &msg, flags);
+ for (;;) {
+ retval = recvmsg(socket, &msg, flags);
+ if (retval == 0) {
+ break;
+ }
+
+ sched_yield();
+ }
done:
uio_copyin_clean(&msg_iov, msg.msg_iovlen);
- dynfree(msg.msg_control);
+ dynfree(control);
return retval;
}