]> 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:57:04 +0000 (18:57 +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)
(cherry picked from commit 4651b2ebc50ad6f7f12ebd4114db4da1a5914f79)

ssl/ssl_lib.c

index a00630e1c32de59aafb1d5c84e58be674b956084..ab76f53feb938628b81fd73d77e92e8052c9dd80 100644 (file)
@@ -3373,18 +3373,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;
 }