# A01 — sqNamedPrims: 1-byte heap overflow on plugin load

Bug ref      : always.md A.1 ; pharo.md §3.26
Severity     : HIGH (heap damage on every plugin load)
File         : extracted/vm/src/common/sqNamedPrims.c
Lines (HEAD) : 51-63

## Problem

`addToModuleList` calls

    calloc(1, sizeof(ModuleEntry) + strlen(pluginName))

then `strcpy(module->name, pluginName)`, which writes `strlen(pluginName)+1`
bytes (the trailing NUL).

`ModuleEntry` declares `char name[1]` as a flexible-array stand-in, so 1
byte for the name is already counted in `sizeof(ModuleEntry)`. The NUL
therefore lands inside the allocation only when the compiler has
preserved trailing padding after `name[1]` (which is normal on 64-bit
ABIs but is not guaranteed; `__attribute__((packed))` or a different
target ABI removes the slack and turns this into a real off-by-one
heap write on every plugin load).

## Fix

Add the explicit `+ 1` for the NUL terminator so the allocation no
longer depends on hidden padding.

```diff
--- a/src/common/sqNamedPrims.c
+++ b/src/common/sqNamedPrims.c
@@ -53,7 +53,7 @@ addToModuleList(char *pluginName, void* handle, sqInt ffiFlag)
 {
 	ModuleEntry *module;
 
-	module = (ModuleEntry*) calloc(1, sizeof(ModuleEntry) + strlen(pluginName));
+	module = (ModuleEntry*) calloc(1, sizeof(ModuleEntry) + strlen(pluginName) + 1);
 	strcpy(module->name, pluginName);
 	module->handle = handle;
 	module->ffiLoaded = ffiFlag;

```

## Test plan

- Build with `-fsanitize=address` and load every shipped plugin.
- Temporarily annotate `ModuleEntry` with `__attribute__((packed))`
  in a local test build — ASAN should report the heap overflow on the
  unfixed code and report clean on the fixed code.

## Risk

Increases each `ModuleEntry` allocation by exactly 1 byte; no other
code reads or relies on the size. Cannot regress runtime behavior.
