[PATCH] powerpc/xmon: add read-only mode
cmr
cmr at informatik.wtf
Fri Mar 29 15:21:53 AEDT 2019
Operations which write to memory should be restricted on secure systems
and optionally to avoid self-destructive behaviors.
Add a config option, XMON_RO, to control default xmon behavior along
with kernel cmdline options xmon=ro and xmon=rw for explicit control.
The default is to enable read-only mode.
The following xmon operations are affected:
memops:
disable memmove
disable memset
memex:
no-op'd mwrite
super_regs:
no-op'd write_spr
bpt_cmds:
disable
proc_call:
disable
Signed-off-by: cmr <cmr at informatik.wtf>
---
arch/powerpc/Kconfig.debug | 7 +++++++
arch/powerpc/xmon/xmon.c | 24 ++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 4e00cb0a5464..33cc01adf4cb 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -117,6 +117,13 @@ config XMON_DISASSEMBLY
to say Y here, unless you're building for a memory-constrained
system.
+config XMON_RO
+ bool "Set xmon read-only mode"
+ depends on XMON
+ default y
+ help
+ Disable state- and memory-altering write operations in xmon.
+
config DEBUGGER
bool
depends on KGDB || XMON
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index a0f44f992360..c13ee73cdfd4 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -80,6 +80,7 @@ static int set_indicator_token = RTAS_UNKNOWN_SERVICE;
#endif
static unsigned long in_xmon __read_mostly = 0;
static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT);
+static int xmon_ro = IS_ENABLED(CONFIG_XMON_RO);
static unsigned long adrs;
static int size = 1;
@@ -1042,6 +1043,8 @@ cmds(struct pt_regs *excp)
set_lpp_cmd();
break;
case 'b':
+ if (xmon_ro == 1)
+ break;
bpt_cmds();
break;
case 'C':
@@ -1055,6 +1058,8 @@ cmds(struct pt_regs *excp)
bootcmds();
break;
case 'p':
+ if (xmon_ro == 1)
+ break;
proccall();
break;
case 'P':
@@ -1777,6 +1782,9 @@ read_spr(int n, unsigned long *vp)
static void
write_spr(int n, unsigned long val)
{
+ if (xmon_ro == 1)
+ return;
+
if (setjmp(bus_error_jmp) == 0) {
catch_spr_faults = 1;
sync();
@@ -2016,6 +2024,10 @@ mwrite(unsigned long adrs, void *buf, int size)
char *p, *q;
n = 0;
+
+ if (xmon_ro == 1)
+ return n;
+
if (setjmp(bus_error_jmp) == 0) {
catch_memory_errors = 1;
sync();
@@ -2884,9 +2896,13 @@ memops(int cmd)
scanhex((void *)&mcount);
switch( cmd ){
case 'm':
+ if (xmon_ro == 1)
+ break;
memmove((void *)mdest, (void *)msrc, mcount);
break;
case 's':
+ if (xmon_ro == 1)
+ break;
memset((void *)mdest, mval, mcount);
break;
case 'd':
@@ -3796,6 +3812,14 @@ static int __init early_parse_xmon(char *p)
} else if (strncmp(p, "on", 2) == 0) {
xmon_init(1);
xmon_on = 1;
+ } else if (strncmp(p, "rw", 2) == 0) {
+ xmon_init(1);
+ xmon_on = 1;
+ xmon_ro = 0;
+ } else if (strncmp(p, "ro", 2) == 0) {
+ xmon_init(1);
+ xmon_on = 1;
+ xmon_ro = 1;
} else if (strncmp(p, "off", 3) == 0)
xmon_on = 0;
else
--
2.21.0
More information about the Linuxppc-dev
mailing list