diff options
author | Helge Deller <deller@gmx.de> | 2017-08-18 11:40:52 +0200 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2017-08-18 11:40:52 +0200 |
commit | 6c29b72066baa54b8822a1f9f206b70f889ed38e (patch) | |
tree | e83cf04d164b603561d54315b0a5185c09fe66b6 | |
parent | d8bafb72b1b8a9365905a9b26e6933b1d63857cd (diff) | |
download | palo-6c29b72066baa54b8822a1f9f206b70f889ed38e.tar.gz |
Prevent overwriting palo during kernel load
Add code to prevent overwriting palo code and data unintentionally
during load of a kernel.
Improve debug output and add the hidden command "d" to toggle debug
mode.
Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r-- | ipl/crt0.S | 2 | ||||
-rw-r--r-- | ipl/ipl.c | 40 |
2 files changed, 37 insertions, 5 deletions
@@ -13,7 +13,9 @@ ;! .section .init .EXPORT $START$,entry + .export _start $START$: +_start: b,n continue ; This branch instruction may be used ; by 'palo' to determine whether a boot ; loader file really is a boot loader, so @@ -15,6 +15,7 @@ #define PAGE0 ((struct zeropage *)0x00000000) char commandline[CMDLINELEN]; +extern char _end, _start, _edata; int Debug = 0; int interactive = 0; @@ -161,6 +162,7 @@ int load_kernel(int fd, unsigned *entryp, int *wide) { struct loadable loadable; + void *malloc_start; int i; if (!prepare_loadable(fd, &loadable, wide)) @@ -176,12 +178,26 @@ load_kernel(int fd, unsigned *entryp, int *wide) printf("\nEntry %08x first %08x n %d\n", loadable.entry, loadable.first, loadable.n); + malloc_start = malloc_aligned(0, 1); + malloc_start -= 5*1024*1024; /* 5 MB */ + for (i = 0; i < loadable.n; i++) { loadable.segment[i].mem = PHYS(loadable.segment[i].mem); printf("Segment %d load %08x size %d mediaptr 0x%lx\n", i, loadable.segment[i].mem, loadable.segment[i].length, loadable.segment[i].offset); + + /* check not to overwrite us */ + if (loadable.segment[i].mem >= (unsigned long)&_end && + (loadable.segment[i].mem + loadable.segment[i].length) + < (unsigned long)malloc_start) + continue; + + printf("Abort: Would overwrite palo %p-%p or data %p areas.\n", + &_start, &_end, malloc_start); + return 0; + } if (!load_loadable((char *)loadable.first, fd, &loadable)) @@ -363,6 +379,9 @@ interact(int *ok) "'r' restore command line\n" "'l' list dir\n" "'x' reset and reboot machine\n" +#ifdef HIDDEN_COMMAND + "'d' toggle debug mode\n" +#endif "? "); numbuf[0] = '0'; numbuf[1] = '\0'; @@ -391,6 +410,16 @@ interact(int *ok) if (numbuf[0] == 'x') pdc_do_reset(); + if (numbuf[0] == 'd') /* hidden option! */ + { + Debug = !Debug; + printf("Debug mode is now %s\n", Debug ? "on":"off"); + if (Debug) + printf("palo loaded at %p-%p.\n", &_start, &_end); + continue; + } + + editfield = parse_number(numbuf, &p); if (editfield >= MAX_ARGV) @@ -444,7 +473,6 @@ get_default_serial_console() unsigned iplmain(int is_interactive, char *initialstackptr, int started_wide) { - extern char _end, _edata; int partitioned; unsigned entry; struct firstblock f; @@ -468,9 +496,12 @@ iplmain(int is_interactive, char *initialstackptr, int started_wide) puts(bld_info); puts("\n"); interactive = is_interactive; - if (Debug) printf("iplmain(%d, started %s)\n", interactive, - started_wide ? "wide" : "narrow"); - if (Debug) printf("initial-sp %p\n", initialstackptr); + if (Debug) { + printf("iplmain(%d, started %s)\n", interactive, + started_wide ? "wide" : "narrow"); + printf("initial-sp %p\n", initialstackptr); + printf("palo loaded at %p-%p.\n", &_start, &_end); + } restart: @@ -704,7 +735,6 @@ iplmain(int is_interactive, char *initialstackptr, int started_wide) } } - /* FIXME!!! This *could* overwrite us -- probably should check */ if (!load_kernel(kernfd, &entry, &wide)) { die("ERROR: failed to load kernel\n"); |