From 6cb56af26c329eb4c5d32f69c0a54232d43c8cc5 Mon Sep 17 00:00:00 2001 From: wfjm Date: Sat, 6 Aug 2022 08:00:53 +0200 Subject: [PATCH] stktst: document the 11/70 findings [skip ci] --- .../data/2022-08-03_simh_3.11_bsd_447.md | 119 +++++++++++++++++- 1 file changed, 116 insertions(+), 3 deletions(-) diff --git a/tools/tests/stktst/data/2022-08-03_simh_3.11_bsd_447.md b/tools/tests/stktst/data/2022-08-03_simh_3.11_bsd_447.md index b268405d..13797c48 100644 --- a/tools/tests/stktst/data/2022-08-03_simh_3.11_bsd_447.md +++ b/tools/tests/stktst/data/2022-08-03_simh_3.11_bsd_447.md @@ -2,8 +2,8 @@ ### Background The `MMR1` response after an MMU abort in an FPP instruction depends on the CPU. -On an 11/70, the registers reflect the state at abort and `MMR1` shows the -change. On a J11, the registers are unchanged, and `MMR1` shows zero. +On an 11/70, the registers reflect the state at abort and `MMR1` returns the +change. On a J11, the registers are unchanged, and `MMR1` returns zero. SimH V3.11-0 used the J11 FPP MMU abort handling for _all_ CPU models. So even when an 11/70 is modeled, the behavior is like a J11. @@ -28,7 +28,7 @@ That leads to two vulnerabilities: - in a SimH 11/70, which probes as an 11/70 but behaves like a J11, any push from an FPP instruction might fail. -The first is a 2.11BSD issue, the second is a SimH issue. +The first is a _2.11BSD issue_, the second is a _SimH issue_. The tests were run under `tcsh`, it gives "Segmentation fault" in case of a problem. Under `sh` one gets "Memory fault". @@ -88,3 +88,116 @@ That's after 25 clicks. The initial stack size is 20 clicks (see [SSIZE](https://www.retro11.de/ouxr/211bsd/usr/src/sys/pdp/machparam.h.html#m:SSIZE)) and the stack segment is a bit larger to accommodate argument and environment structures. So the `double` pushes fail when the initial allocation is exhausted. + +### SimH in 11/70 mode, FPP enabled +SimH pdp11 started with +``` +set cpu 11/70 +``` +and 2.11BSD starts with +``` +70Boot from xp(0,0,0) at 0176700 +``` +The CPU probes now as 11/70, indicated by the `70Boot` startup message, +but behaves like a J11 for `MMR1`. The 2.11BSD J11 hack isn't done and +_all_ FPP pushes are vulnerable. That's what tests show: +``` +# word push from FPP +./stktst i '4096' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # Segmentation fault (core dumped) + ./stktst i ' 607' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 174700 (0, 24,64); +./stktst i ' 608' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); +# +# long push from FPP +./stktst l '2048' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # Segmentation fault (core dumped) +./stktst l ' 303' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 174702 (0, 24,62); +./stktst l ' 304' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # Segmentation fault (core dumped) +# +# float push from FPP +./stktst f '2048' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # Segmentation fault (core dumped) +./stktst f ' 303' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 174702 (0, 24,62); +./stktst f ' 304' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # Segmentation fault (core dumped) +# +# double push from FPP +./stktst d '1024' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # Segmentation fault (core dumped) +./stktst d ' 151' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 174706 (0, 24,58); +./stktst d ' 152' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # Segmentation fault (core dumped) +``` +All FPP pushes fail when the first stack extend is reached. +This is, as stated before, not a 2.11BSD issue but a SimH issue. + +### SimH in 11/70 mode, FPP disabled +SimH pdp11 started with +``` +set cpu 11/70 +set cpu nofpp +``` +and 2.11BSD starts with +``` +70Boot from xp(0,0,0) at 0176700 +``` +All FPP instructions trap and are emulated by a kernel mode handler with +plain integer arithmetic. Stack extends work as expected: +``` +./stktst d '1024' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 157176 (1, 6, 2); +# fill 2 pages +./stktst d '1999' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 140006 (1,127,58); +# fill 3 pages +./stktst d '3023' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 120006 (2,127,58); +# fill 5 pages +./stktst d '5071' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 060006 (4,127,58); +# fill 6 pages +./stktst d '6095' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 040006 (5,127,58); +# fill 7 pages +./stktst d '7119' -c ' 2' -o ' -2' + # stktst-I: before sp 177304 (0, 4,60); 177176 (0, 6, 2); + # stktst-I: after sp 177304 (0, 4,60); 177176 (0, 6, 2); 020006 (6,127,58); +``` +`stktst` doesn't use separate I/D space, so page 0 is used by code and data. +The stack segment can't grow larger than 7 pages, and an extension beyond must +fail. And it does fail, a bit more spectacular than it should: +``` +# and try one more +./stktst d '7120' -c ' 2' -o ' -2' + # ka6 36722 aps 147472 + # pc 161324 ps 30004 + # ov 4 + # cpuerr 20 + # trap type 0 + # panic: trap + # syncing disks... done +``` +The _kernel panic_ must come from a bug in the 2.11BSD FPP emulation code +[mch_fpsim.s](https://www.retro11.de/ouxr/211bsd/usr/src/sys/pdp/mch_fpsim.s.html). It should forward a SIGSEGV to the user process, like is does for other captured faults (like in code around [ferr1](https://www.retro11.de/ouxr/211bsd/usr/src/sys/pdp/mch_fpsim.s.html#s:ferr1)).