]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ktls_read_record(): Harden linux recv path
authorJoshua Rogers <MegaManSec@users.noreply.github.com>
Sat, 11 Oct 2025 06:19:28 +0000 (14:19 +0800)
committerTomas Mraz <tomas@openssl.org>
Thu, 11 Dec 2025 11:45:42 +0000 (12:45 +0100)
- drop tag subtraction in recv buffer sizing
- enforce MSG_EOR and reject MSG_CTRUNC
- zero prepended header bytes before recvmsg

Signed-off-by: Joshua Rogers <MegaManSec@users.noreply.github.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28861)

include/internal/ktls.h

index 83f66b9dba93998e8dd94ac54045397f5e847347..8c9b12cfe236ef99465db56439323fb3337033c4 100644 (file)
@@ -407,7 +407,7 @@ static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
     unsigned char *p = data;
     const size_t prepend_length = SSL3_RT_HEADER_LENGTH;
 
-    if (length < prepend_length + EVP_GCM_TLS_TAG_LEN) {
+    if (length < prepend_length) {
         errno = EINVAL;
         return -1;
     }
@@ -417,17 +417,27 @@ static ossl_inline int ktls_read_record(int fd, void *data, size_t length)
     msg.msg_controllen = sizeof(cmsgbuf.buf);
 
     msg_iov.iov_base = p + prepend_length;
-    msg_iov.iov_len = length - prepend_length - EVP_GCM_TLS_TAG_LEN;
+    msg_iov.iov_len = length - prepend_length;
     msg.msg_iov = &msg_iov;
     msg.msg_iovlen = 1;
 
+    memset(p, 0, prepend_length);
+
     ret = recvmsg(fd, &msg, 0);
     if (ret < 0)
         return ret;
 
+    if ((msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) != MSG_EOR) {
+        errno = EMSGSIZE;
+        return -1;
+    }
+
     if (msg.msg_controllen > 0) {
         cmsg = CMSG_FIRSTHDR(&msg);
-        if (cmsg->cmsg_type == TLS_GET_RECORD_TYPE) {
+        if (cmsg != NULL
+            && cmsg->cmsg_level == SOL_TLS
+            && cmsg->cmsg_type == TLS_GET_RECORD_TYPE
+            && cmsg->cmsg_len >= CMSG_LEN(sizeof(unsigned char))) {
             p[0] = *((unsigned char *)CMSG_DATA(cmsg));
             p[1] = TLS1_2_VERSION_MAJOR;
             p[2] = TLS1_2_VERSION_MINOR;