syscall: fix call source detection

This commit is contained in:
anna 2021-08-02 00:37:01 +02:00
parent aa722fc34f
commit 57fb52dc1e
Signed by: fef
GPG key ID: EC22E476DC2D3D84
4 changed files with 14 additions and 12 deletions
arch/at91sam3x8e

View file

@ -13,7 +13,7 @@
#ifdef CONFIG_CHECK_SYSCALL_SOURCE #ifdef CONFIG_CHECK_SYSCALL_SOURCE
/* syscall.S */ /* syscall.S */
extern uintptr_t __syscall_entry_point; extern uint16_t __syscall_return_point;
#endif #endif
void arch_enter(void *sp) void arch_enter(void *sp)
@ -27,10 +27,11 @@ void arch_enter(void *sp)
# ifdef CONFIG_CHECK_SYSCALL_SOURCE # ifdef CONFIG_CHECK_SYSCALL_SOURCE
/* /*
* We need to ignore the program counter's LSB because the CPU uses * We need to ignore the program counter's LSB because the CPU uses
* that as a flag for whether it's operating in ARM or Thumb mode * that as a flag for whether it's operating in ARM or Thumb mode;
* (1 for Thumb); the instructions are always 2-byte aligned. * the instructions are always 2-byte aligned. Additionally, the PC
* points to the instruction *after* the SVC, not SVC itself.
*/ */
if ((regs->hw.pc & 0xfffffffe) != __syscall_entry_point) { if (((uintptr_t)regs->hw.pc & 0xfffffffe) != (uintptr_t)&__syscall_return_point) {
arch_syscall_set_rval(regs, -EACCES); arch_syscall_set_rval(regs, -EACCES);
return; return;
} }

View file

@ -29,7 +29,7 @@ struct reg_sw_snapshot {
* lr is saved by hardware, but we need to store it twice * lr is saved by hardware, but we need to store it twice
* because the IRQ entry overwrites it * because the IRQ entry overwrites it
*/ */
uintptr_t lr; /* alias r14 */ void *lr; /* alias r14 */
}; };
/** /**
@ -42,8 +42,8 @@ struct reg_hw_snapshot {
word_t r2; word_t r2;
word_t r3; word_t r3;
word_t r12; word_t r12;
uintptr_t lr; /* alias r14 */ void *lr; /* alias r14 */
uintptr_t pc; /* alias r15 */ void *pc; /* alias r15 */
word_t psr; word_t psr;
}; };

View file

@ -61,9 +61,9 @@ void arch_sched_task_init(struct task *task, void (*entry)(void))
task->sp = regs; task->sp = regs;
memset(regs, 0, sizeof(*regs)); memset(regs, 0, sizeof(*regs));
regs->hw.pc = (uintptr_t)entry; regs->hw.pc = entry;
regs->hw.psr = 0x01000000U; regs->hw.psr = 0x01000000;
regs->sw.lr = 0xfffffff9U; regs->sw.lr = (void *)0xfffffff9;
} }
void yield(enum task_state state) void yield(enum task_state state)

View file

@ -5,6 +5,8 @@
/* this is only invoked from user space, obviously */ /* this is only invoked from user space, obviously */
.section .text.shared .section .text.shared
.global __syscall_return_point
/* int syscall(int number, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6); */ /* int syscall(int number, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6); */
func_begin syscall func_begin syscall
@ -32,10 +34,9 @@ func_begin syscall
ldr r4, [sp, #16] /* arg5 */ ldr r4, [sp, #16] /* arg5 */
ldr r5, [sp, #20] /* arg6 */ ldr r5, [sp, #20] /* arg6 */
.global __syscall_entry_point
__syscall_entry_point:
svc #0 svc #0
__syscall_return_point:
pop {r4-r5,r7} pop {r4-r5,r7}
/* r0 (return value) is set by the kernel */ /* r0 (return value) is set by the kernel */