From: Tulio A M Mendes Date: Mon, 25 May 2026 19:23:16 +0000 (-0300) Subject: security: Round 6.4 socket copy_to_user SMAP compliance (K35) X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=165d81c4e29137617aff2750bbd9f0b9afb383e1;p=AdrOS.git security: Round 6.4 socket copy_to_user SMAP compliance (K35) K35: Add bounce buffers to sendmsg/recvmsg for SMAP compliance - sendmsg: copy_from_user to kernel buffer before ksocket_send/ksocket_sendto - recvmsg: ksocket_recvfrom to kernel buffer, then copy_to_user to user buffer - Bounce buffer size limited to 4096 bytes per iov entry - Ensures SMAP compliance by not passing user buffers directly to lwIP Tests: 119/119 PASS (smoke test, SMP=4) --- diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 68bfd8e1..2a228a42 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -4708,11 +4708,23 @@ static int syscall_sendmsg_impl(int sockfd, void* user_msg, int flags) { return -EFAULT; if (kiov.len == 0) continue; if (!user_range_ok(kiov.base, kiov.len)) return -EFAULT; + + /* K35: Use bounce buffer for SMAP compliance */ + size_t xfer = (kiov.len > 4096) ? 4096 : kiov.len; + uint8_t* kbuf = (uint8_t*)kmalloc(xfer); + if (!kbuf) return (total > 0) ? total : -ENOMEM; + if (copy_from_user(kbuf, kiov.base, xfer) < 0) { + kfree(kbuf); + return (total > 0) ? total : -EFAULT; + } + int ret; if (has_dest) - ret = ksocket_sendto(sid, kiov.base, kiov.len, flags, &dest); + ret = ksocket_sendto(sid, kbuf, xfer, flags, &dest); else - ret = ksocket_send(sid, kiov.base, kiov.len, flags); + ret = ksocket_send(sid, kbuf, xfer, flags); + kfree(kbuf); + if (ret < 0) return (total > 0) ? total : ret; total += ret; } @@ -4739,10 +4751,24 @@ static int syscall_recvmsg_impl(int sockfd, void* user_msg, int flags) { return -EFAULT; if (kiov.len == 0) continue; if (!user_range_ok(kiov.base, kiov.len)) return -EFAULT; - int ret = ksocket_recvfrom(sid, kiov.base, kiov.len, flags, &src); + + /* K35: Use bounce buffer for SMAP compliance */ + size_t xfer = (kiov.len > 4096) ? 4096 : kiov.len; + uint8_t* kbuf = (uint8_t*)kmalloc(xfer); + if (!kbuf) return (total > 0) ? total : -ENOMEM; + + int ret = ksocket_recvfrom(sid, kbuf, xfer, flags, &src); + if (ret > 0) { + if (copy_to_user(kiov.base, kbuf, (size_t)ret) < 0) { + kfree(kbuf); + return (total > 0) ? total : -EFAULT; + } + } + kfree(kbuf); + if (ret < 0) return (total > 0) ? total : ret; total += ret; - if ((uint32_t)ret < kiov.len) break; + if ((uint32_t)ret < xfer) break; } if (kmsg.name && kmsg.namelen >= sizeof(src))