summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2017-08-18 11:40:52 +0200
committerHelge Deller <deller@gmx.de>2017-08-18 11:40:52 +0200
commit6c29b72066baa54b8822a1f9f206b70f889ed38e (patch)
treee83cf04d164b603561d54315b0a5185c09fe66b6
parentd8bafb72b1b8a9365905a9b26e6933b1d63857cd (diff)
downloadpalo-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.S2
-rw-r--r--ipl/ipl.c40
2 files changed, 37 insertions, 5 deletions
diff --git a/ipl/crt0.S b/ipl/crt0.S
index d52485f..34dfc8c 100644
--- a/ipl/crt0.S
+++ b/ipl/crt0.S
@@ -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
diff --git a/ipl/ipl.c b/ipl/ipl.c
index 19111d8..1a6d946 100644
--- a/ipl/ipl.c
+++ b/ipl/ipl.c
@@ -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");