# B28 — CMakeLists: Windows/Cygwin builds lack /GS, /guard:cf, /DYNAMICBASE, /NXCOMPAT

Bug ref      : always.md B.28 ; pharo.md §7
Severity     : HIGH (Windows binaries ship without standard mitigations)
File         : CMakeLists.txt
Lines (HEAD) : ~206

## Problem

The Windows build does not enable:

  - `/GS`         — stack canaries on functions with stack buffers.
  - `/guard:cf`   — Control Flow Guard, prevents indirect-call
                    hijack to unintended targets.
  - `/DYNAMICBASE` — PE header bit that lets the loader randomise
                    image base (ASLR).
  - `/NXCOMPAT`   — PE header bit declaring the binary is compatible
                    with DEP (no-execute pages).

Without these, exploits for any memory bug in the VM run with all
the standard Windows mitigations turned off.

## Fix

Add an MSVC/cygwin hardening block.

```diff
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ec39df40..a05687198 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -209,6 +209,20 @@ elseif(WIN)
     set(OS_TYPE "Win32")
     set(VM_TARGET_OS "Win64")
 
+    # Windows hardening flags. Off by default; opt in via -DPHARO_HARDENED=ON
+    # to avoid surprising existing builds.
+    option(PHARO_HARDENED "Enable hardening flags for the Windows build" OFF)
+    if(PHARO_HARDENED)
+        if(MSVC)
+            add_compile_options(/GS /guard:cf /sdl)
+            add_link_options(/DYNAMICBASE /NXCOMPAT /guard:cf /HIGHENTROPYVA)
+        else()
+            # MinGW / Cygwin: gcc-style hardening.
+            add_compile_options(-fstack-protector-strong)
+            add_link_options(-Wl,--dynamicbase -Wl,--nxcompat -Wl,--high-entropy-va)
+        endif()
+    endif()
+
     # this one is important
     SET(CMAKE_SYSTEM_NAME Windows)
```

For MinGW/cygwin (which use gcc-style flags), the equivalent is:



(Pick the branch that matches the actual toolchain in your Windows
build; the Pharo Windows pipeline uses Cygwin-MinGW.)

## Test plan

- Build the Windows variant. Confirm successful build.
- `dumpbin /HEADERS pharo.exe | grep -E 'DLL Characteristics|GuardCF'`:
  the DLL Characteristics field should include `Dynamic base`,
  `NX compatible`, `Control Flow Guard`.
- Or via `python -c "import lief; b = lief.parse('pharo.exe');
  print(b.optional_header.dll_characteristics)"`.

## Risk notes

- `/GS` and `/guard:cf` have small but real runtime cost
  (single-digit percent for typical workloads). The audit's
  judgement is that the safety win is worth it for a VM that hosts
  arbitrary user code.
- `/guard:cf` requires the linker to be invoked with `/guard:cf`
  too (already in the diff).
- For Cygwin-mingw builds, `-mguard=cf` requires gcc 13+; check the
  toolchain on the CI runner.
