Re: [PATCH v2 1/4] sandbox: add handler for exceptions

2020-12-09 Thread Simon Glass
On 17.11.20 00:53, Simon Glass wrote:
> Hi Heinrich,
>
> On Wed, 11 Nov 2020 at 16:30, Heinrich Schuchardt  wrote:
>>
>> Add a handler for SIGILL, SIGBUS, SIGSEGV.
>>
>> When an exception occurs print the program counter and the loaded
>> UEFI binaries and reset the system if CONFIG_SANDBOX_CRASH_RESET=y
>> or exit to the OS otherwise.
>>
>> Signed-off-by: Heinrich Schuchardt 
>> ---
>> v2:
>> add a customizing switch
>> set SA_NODEFER flag for sigaction
>> ---
>>  arch/sandbox/Kconfig  |  9 
>>  arch/sandbox/cpu/os.c | 40 +++
>>  arch/sandbox/cpu/start.c  |  4 
>>  arch/sandbox/lib/interrupts.c | 35 ++
>>  include/os.h  | 17 +++
>>  5 files changed, 105 insertions(+)
>
> Reviewed-by: Simon Glass 
>
> Do you think a command-line flag might be useful too/instead?
>

For my needs the CONFIG flag is enough.

I could not find the mail for patch 2/4 in my inbox.
I have tested on aarch64 that the exception work here too.

Best regards

Heinrich

Applied to u-boot-dm, thanks!


Re: [PATCH v2 1/4] sandbox: add handler for exceptions

2020-11-19 Thread Heinrich Schuchardt
On 17.11.20 00:53, Simon Glass wrote:
> Hi Heinrich,
>
> On Wed, 11 Nov 2020 at 16:30, Heinrich Schuchardt  wrote:
>>
>> Add a handler for SIGILL, SIGBUS, SIGSEGV.
>>
>> When an exception occurs print the program counter and the loaded
>> UEFI binaries and reset the system if CONFIG_SANDBOX_CRASH_RESET=y
>> or exit to the OS otherwise.
>>
>> Signed-off-by: Heinrich Schuchardt 
>> ---
>> v2:
>> add a customizing switch
>> set SA_NODEFER flag for sigaction
>> ---
>>  arch/sandbox/Kconfig  |  9 
>>  arch/sandbox/cpu/os.c | 40 +++
>>  arch/sandbox/cpu/start.c  |  4 
>>  arch/sandbox/lib/interrupts.c | 35 ++
>>  include/os.h  | 17 +++
>>  5 files changed, 105 insertions(+)
>
> Reviewed-by: Simon Glass 
>
> Do you think a command-line flag might be useful too/instead?
>

For my needs the CONFIG flag is enough.

I could not find the mail for patch 2/4 in my inbox.
I have tested on aarch64 that the exception work here too.

Best regards

Heinrich


Re: [PATCH v2 1/4] sandbox: add handler for exceptions

2020-11-16 Thread Simon Glass
Hi Heinrich,

On Wed, 11 Nov 2020 at 16:30, Heinrich Schuchardt  wrote:
>
> Add a handler for SIGILL, SIGBUS, SIGSEGV.
>
> When an exception occurs print the program counter and the loaded
> UEFI binaries and reset the system if CONFIG_SANDBOX_CRASH_RESET=y
> or exit to the OS otherwise.
>
> Signed-off-by: Heinrich Schuchardt 
> ---
> v2:
> add a customizing switch
> set SA_NODEFER flag for sigaction
> ---
>  arch/sandbox/Kconfig  |  9 
>  arch/sandbox/cpu/os.c | 40 +++
>  arch/sandbox/cpu/start.c  |  4 
>  arch/sandbox/lib/interrupts.c | 35 ++
>  include/os.h  | 17 +++
>  5 files changed, 105 insertions(+)

Reviewed-by: Simon Glass 

Do you think a command-line flag might be useful too/instead?


[PATCH v2 1/4] sandbox: add handler for exceptions

2020-11-11 Thread Heinrich Schuchardt
Add a handler for SIGILL, SIGBUS, SIGSEGV.

When an exception occurs print the program counter and the loaded
UEFI binaries and reset the system if CONFIG_SANDBOX_CRASH_RESET=y
or exit to the OS otherwise.

Signed-off-by: Heinrich Schuchardt 
---
v2:
add a customizing switch
set SA_NODEFER flag for sigaction
---
 arch/sandbox/Kconfig  |  9 
 arch/sandbox/cpu/os.c | 40 +++
 arch/sandbox/cpu/start.c  |  4 
 arch/sandbox/lib/interrupts.c | 35 ++
 include/os.h  | 17 +++
 5 files changed, 105 insertions(+)

diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 65f988e736..f83282d9d5 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -51,6 +51,15 @@ config HOST_64BIT

 endchoice

+config SANDBOX_CRASH_RESET
+   bool "Reset on crash"
+   help
+ If an illegal instruction or an illegal memory access occurs, the
+ sandbox by default writes a crash dump and exits. If you set this
+ flag, the sandbox is reset instead. This may be useful when running
+ test suites like the UEFI self certification test which continue
+ with the next test after a crash.
+
 config SANDBOX_BITS_PER_LONG
int
default 32 if HOST_32BIT
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 0d8efd83f6..b56fa04a34 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2011 The Chromium OS Authors.
  */

+#define _GNU_SOURCE
+
 #include 
 #include 
 #include 
@@ -15,11 +17,13 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 

 #include 
@@ -191,6 +195,42 @@ static void os_sigint_handler(int sig)
raise(SIGINT);
 }

+static void os_signal_handler(int sig, siginfo_t *info, void *con)
+{
+   ucontext_t __maybe_unused *context = con;
+   unsigned long pc;
+
+#if defined(__x86_64__)
+   pc = context->uc_mcontext.gregs[REG_RIP];
+#elif defined(__aarch64__)
+   pc = context->uc_mcontext.pc;
+#elif defined(__riscv)
+   pc = context->uc_mcontext.__gregs[REG_PC];
+#else
+   const char msg[] =
+   "\nUnsupported architecture, cannot read program counter\n";
+
+   os_write(1, msg, sizeof(msg));
+   pc = 0;
+#endif
+
+   os_signal_action(sig, pc);
+}
+
+int os_setup_signal_handlers(void)
+{
+   struct sigaction act;
+
+   act.sa_sigaction = os_signal_handler;
+   sigemptyset(_mask);
+   act.sa_flags = SA_SIGINFO | SA_NODEFER;
+   if (sigaction(SIGILL, , NULL) ||
+   sigaction(SIGBUS, , NULL) ||
+   sigaction(SIGSEGV, , NULL))
+   return -1;
+   return 0;
+}
+
 /* Put tty into raw mode so  and  work */
 void os_tty_raw(int fd, bool allow_sigs)
 {
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index a03e5aa0b3..f6c98545e0 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -451,6 +451,10 @@ int main(int argc, char *argv[])
if (ret)
goto err;

+   ret = os_setup_signal_handlers();
+   if (ret)
+   goto err;
+
 #if CONFIG_VAL(SYS_MALLOC_F_LEN)
gd->malloc_base = CONFIG_MALLOC_F_ADDR;
 #endif
diff --git a/arch/sandbox/lib/interrupts.c b/arch/sandbox/lib/interrupts.c
index 21f761ac3b..9c2c60b8c6 100644
--- a/arch/sandbox/lib/interrupts.c
+++ b/arch/sandbox/lib/interrupts.c
@@ -6,7 +6,13 @@
  */

 #include 
+#include 
 #include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;

 int interrupt_init(void)
 {
@@ -21,3 +27,32 @@ int disable_interrupts(void)
 {
return 0;
 }
+
+void os_signal_action(int sig, unsigned long pc)
+{
+   efi_restore_gd();
+
+   switch (sig) {
+   case SIGILL:
+   printf("\nIllegal instruction\n");
+   break;
+   case SIGBUS:
+   printf("\nBus error\n");
+   break;
+   case SIGSEGV:
+   printf("\nSegmentation violation\n");
+   break;
+   default:
+   break;
+   }
+   printf("pc = 0x%lx, ", pc);
+   printf("pc_reloc = 0x%lx\n\n", pc - gd->reloc_off);
+   efi_print_image_infos((void *)pc);
+
+   if (IS_ENABLED(CONFIG_SANDBOX_CRASH_RESET)) {
+   printf("resetting ...\n\n");
+   sandbox_reset();
+   } else {
+   sandbox_exit();
+   }
+}
diff --git a/include/os.h b/include/os.h
index 1fe44f3510..0913b47b3a 100644
--- a/include/os.h
+++ b/include/os.h
@@ -407,4 +407,21 @@ void *os_find_text_base(void);
  */
 void os_relaunch(char *argv[]);

+/**
+ * os_setup_signal_handlers() - setup signal handlers
+ *
+ * Install signal handlers for SIGBUS and SIGSEGV.
+ *
+ * Return: 0 for success
+ */
+int os_setup_signal_handlers(void);
+
+/**
+ * os_signal_action() - handle a signal
+ *
+ * @sig:   signal
+ * @pc: