# Extended 3.18 — sqUnixSSL sqConnectSSL/sqAcceptSSL: peerName from uninitialised stack

Bug ref      : pharo.md §3.18
Severity     : HIGH (info leak; OOB read on subsequent property access)
File         : extracted/plugins/SqueakSSL/src/unix/sqUnixSSL.c
Lines (HEAD) : 319-330 (`sqConnectSSL` NO_MATCH_DONE_YET fallback), 405-417 (`sqAcceptSSL`)

## Problem

```c
char peerName[254];               // STACK, uninitialised
X509_NAME_get_text_by_NID(..., peerName, sizeof(peerName));   // ret ignored
logTrace("sqConnectSSL: peerName = %s\n", peerName);
ssl->peerName = strndup(peerName, sizeof(peerName) - 1);
```

When the cert lacks the requested NID, `X509_NAME_get_text_by_NID`
returns `-1` and **does not write `peerName`**. The subsequent
`logTrace` prints stack garbage up to the first NUL, and `strndup`
copies that garbage into the image as `ssl->peerName`. Downstream
`primitiveGetStringProperty` reads `strlen` on the strndup'd buffer;
if no NUL appeared within the bounds, strlen runs into adjacent heap.

## Fix

Zero the buffer; check the return value.

```diff
diff --git a/extracted/plugins/SqueakSSL/src/unix/sqUnixSSL.c b/extracted/plugins/SqueakSSL/src/unix/sqUnixSSL.c
index 1af71037e..4899299b0 100644
--- a/extracted/plugins/SqueakSSL/src/unix/sqUnixSSL.c
+++ b/extracted/plugins/SqueakSSL/src/unix/sqUnixSSL.c
@@ -323,11 +323,19 @@ sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt
 		}
 		// fallback for missing sAN or non-provided serverName
 		if (matched == NO_MATCH_DONE_YET || matched == NO_SAN_PRESENT) {
-			X509_NAME_get_text_by_NID(X509_get_subject_name(cert),
+			int nidLen;
+			memset(peerName, 0, sizeof(peerName));
+			nidLen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert),
 						      NID_commonName, peerName,
 						      sizeof(peerName));
-			logTrace("sqConnectSSL: peerName = %s\n", peerName);
-			ssl->peerName = strndup(peerName, sizeof(peerName) - 1);
+			if (nidLen <= 0) {
+				/* No CN field; previously left peerName uninitialised
+				 * and printed stack bytes via logTrace. */
+				ssl->peerName = strdup("");
+			} else {
+				logTrace("sqConnectSSL: peerName = %s\n", peerName);
+				ssl->peerName = strndup(peerName, sizeof(peerName) - 1);
+			}
 		}
 		X509_free(cert);
 
```



## Test plan

- Connect to a server whose cert has no CN field. Before: `peerName`
  comes from stack garbage. After: peerName is the empty string.
- Normal cert with a CN: unchanged.

## Risk notes

- `memset` + return-value check is the standard defensive pattern
  for OpenSSL's `X509_NAME_get_text_by_NID`.
- An empty `ssl->peerName` is a safer signal to the image than
  random stack bytes; the image-side `peerName` check will compare
  against `serverName` and detect the mismatch.
