duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 60edd420cc32c189d716d5a847019702ab4f7563
parent 18d90eef8d5046602150136d377784a69758e0ac
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Mon,  8 May 2023 22:40:55 -0400

posix/vm: add memory protection mechanism

very useful for debugging memory corruption.

Diffstat:
Mposix/vm.c | 21+++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/posix/vm.c b/posix/vm.c @@ -91,6 +91,8 @@ struct VM { dword W; // W is PS top dword A; dword T; // tmp register. not directly addressable + dword mprotect; // halt when protected memory is changed + dword mprotectsz; byte Z; byte C; byte SC; // signed C @@ -111,10 +113,17 @@ static dword mainaddr; static void vmabort() { vm.PC = MEMSZ + 1; } static dword memchk(dword a) { if (a < MEMSZ) return a; - printf("Out of bounds memory access! Halting"); + printf("Out of bounds memory access! Halting\n"); vmabort(); return 0; } +static dword memchkmut(dword a) { + if ((a >= vm.mprotect) && (a < vm.mprotect + vm.mprotectsz)) { + printf("Access to protected memory! Halting\n"); + vmabort(); + return 0; + } else { return a; } +} static byte gb(dword addr) { return vm.mem[memchk(addr)]; } static word gw(dword addr) { return gb(addr) | (gb(addr+1)<<8); } static dword gd(dword addr) { return gw(addr) | (gw(addr+2)<<16); } @@ -130,7 +139,7 @@ static dword gdr(dword addr) { } static dword gpc() { dword n = gd(vm.PC); vm.PC += 4; return n; } static byte gpcb() { dword n = gb(vm.PC); vm.PC++; return n; } -static void sb(dword addr, byte b) { vm.mem[memchk(addr)] = b; } +static void sb(dword addr, byte b) { vm.mem[memchkmut(addr)] = b; } static void sw(dword addr, word w) { sb(addr, w); sb(addr+1, w>>8); } static void sd(dword addr, dword d) { sw(addr, d); sw(addr+2, d>>16); } static void sdr(dword addr, dword d) { @@ -595,6 +604,8 @@ static void DBG() { printf("RS "); _stackdump(vm.RSP, RSTOP); } static void USLEEP() { usleep(ppop()); } +// ( a u -- ) +static void MPROTECT() { vm.mprotectsz = ppop(); vm.mprotect = ppop(); } // 0x60 static void WCHECKZ() { vm.Z = !vm.W; } @@ -894,7 +905,7 @@ static void (*ops[OPCNT])() = { STACKCHK, COMPWORD, RUNWORD, COMPILING, STARTCOMP, STOPCOMP, RSADDWR, COMPOP, ALIGN4, ENTRY, CODE, CODE16, CODE8, COMPBINOP, NULL, NULL, WBINOP, WBINOP16, WBINOP8, DIVMOD, NULL, LT, NEG, NULL, - BYE, BYEFAIL, QUIT, ABORT_, DBG, USLEEP, NULL, NULL, + BYE, BYEFAIL, QUIT, ABORT_, DBG, USLEEP, MPROTECT, NULL, NULL, NULL, NULL, NULL, NULL, WCHECKZ, STOREC, ACHECKZ, FCHILD, FOPEN, FREADBUF, FCLOSE, FINFO, FITER, NULL, FSEEK, MOUNTDRV, UNMOUNTDRV, DRVRD, DRVWR, NULL, NULL, NULL, NULL, @@ -937,7 +948,7 @@ static char *opnames[OPCNT-0x28] = { "stack?", "compword", "runword", "compiling", "]", NULL, "rs+,", NULL, "align4", "entry", "code", "code16b", "code8b", NULL, NULL, NULL, NULL, NULL, NULL, "/mod", NULL, "<", NULL, NULL, - "bye", "byefail", "quit", "(abort)", "dbg", "_usleep", NULL, NULL, + "bye", "byefail", "quit", "(abort)", "dbg", "_usleep", "mprotect", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "_fchild", "_fopen", "_freadbuf", "_fclose", "_finfo", "_fiter", NULL, "_fseek", "_mountdrv", "_unmountdrv", "_drv@", "_drv!", NULL, NULL, NULL, NULL @@ -1053,10 +1064,12 @@ int main() { return 1; } buildsysdict(); + vm.mprotectsz = 0; vm.PC = find("(abort)"); while (vm.PC < MEMSZ) oprun1(); if (fp) fclose(fp); if (vm.PC > MEMSZ) { + DBG(); fprintf(stderr, "Dumping memory to memdump.\n"); FILE *fp = fopen("memdump", "w"); fwrite(vm.mem, MEMSZ, 1, fp);