aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
authorJamie Garside <jamie.garside@york.ac.uk>2015-02-23 10:35:35 -0500
committerMichal Simek <michal.simek@xilinx.com>2015-03-04 09:12:27 -0500
commitc2219eda547813c0c50dba90d9e989ae36cc3ab8 (patch)
tree79e5d3d4810030c686e84403f274bfd1c952afa5 /arch/microblaze
parent074fa7e76cfff4cd1a60753ee4596510f1b87183 (diff)
microblaze: Fix syscall error recovery for invalid syscall IDs
This patch fixes two bugs in the Microblaze syscall trap handler when an invalid syscall ID is used. First, the range check on line 351 only checks for syscall IDs greater than __NR_syscalls. A negative syscall ID (either passed to `syscall()` or as returned by `do_syscall_trace_enter()` on error) will still satisfy this test and cause the Linux kernel to access an invalid memory location and cause a kernel oops. This has been fixed by also checking for r12 < 0. Secondly, the current error recovery at line 378 returns using the wrong register (r15 instead of r14) and does not restore the previous stack state. This has been fixed by invoking `ret_from_trap` on error, setting r3 to `-ENOSYS`, similar to what would happen when calling a valid syscall. Signed-off-by: Jamie Garside <jamie.garside@york.ac.uk> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/kernel/entry.S3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 5dcb0e1a41c4..ef548510b951 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -348,6 +348,7 @@ C_ENTRY(_user_exception):
348 * The LP register should point to the location where the called function 348 * The LP register should point to the location where the called function
349 * should return. [note that MAKE_SYS_CALL uses label 1] */ 349 * should return. [note that MAKE_SYS_CALL uses label 1] */
350 /* See if the system call number is valid */ 350 /* See if the system call number is valid */
351 blti r12, 5f
351 addi r11, r12, -__NR_syscalls; 352 addi r11, r12, -__NR_syscalls;
352 bgei r11, 5f; 353 bgei r11, 5f;
353 /* Figure out which function to use for this system call. */ 354 /* Figure out which function to use for this system call. */
@@ -375,7 +376,7 @@ C_ENTRY(_user_exception):
375 376
376 /* The syscall number is invalid, return an error. */ 377 /* The syscall number is invalid, return an error. */
3775: 3785:
378 rtsd r15, 8; /* looks like a normal subroutine return */ 379 braid ret_from_trap
379 addi r3, r0, -ENOSYS; 380 addi r3, r0, -ENOSYS;
380 381
381/* Entry point used to return from a syscall/trap */ 382/* Entry point used to return from a syscall/trap */