]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ssl: fix OOB write in SSL_get_shared_ciphers when no shared ciphers
authorJoshua Rogers <MegaManSec@users.noreply.github.com>
Wed, 8 Oct 2025 22:14:15 +0000 (06:14 +0800)
committerTomas Mraz <tomas@openssl.org>
Fri, 17 Oct 2025 16:56:38 +0000 (18:56 +0200)
When no cipher names are appended, p remains at buf and the unconditional
p[-1] = '\0' underflows. Only NUL-terminate if at least one cipher was written;
otherwise return an empty string safely.

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/28785)

(cherry picked from commit 680491a2a7403fc6e5e1759e0eabeceeacaf37f9)

ssl/ssl_lib.c

index 582c9afebfff3aa96bf9ba52ebcac680098e382e..eb8e380b3ce8fa2f1bf95abaf8100d2dbb34db3c 100644 (file)
@@ -3393,18 +3393,20 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size)
         if (sk_SSL_CIPHER_find(srvrsk, c) < 0)
             continue;
 
-        n = OPENSSL_strnlen(c->name, size);
-        if (n >= size) {
-            if (p != buf)
-                --p;
-            *p = '\0';
-            return buf;
-        }
+        n = (int)OPENSSL_strnlen(c->name, size);
+        if (n >= size)
+            break;
+
         memcpy(p, c->name, n);
         p += n;
         *(p++) = ':';
         size -= n + 1;
     }
+
+    /* No overlap */
+    if (p == buf)
+        return NULL;
+
     p[-1] = '\0';
     return buf;
 }