[Xenomai] Crash with longer dlopen/dlcose sequence

Philippe Gerum rpm at xenomai.org
Sat May 12 19:08:21 CEST 2018


On 05/09/2018 12:27 PM, Edouard Tisserant wrote:
> 
>>> [Xenomai] bad syscall <0xf0002>
>> #define __ARM_NR_BASE           (__NR_SYSCALL_BASE+0x0f0000)
>> #define __ARM_NR_cacheflush     (__ARM_NR_BASE+2)
> 
> This special syscall is issued by Glibc in _dl_reloacate_object (see
> /elf/dl-reloc.c and /sysdeps/unix/sysv/linux/arm/dl-machine.h)
> 
> As a workaround, rebuilding everything with -fPIC avoids relocation, and
> then bad syscall.
> 

Thanks for digging this out. Could you try this patch, keeping the relocation enabled in your build? TIA,

diff --git a/kernel/cobalt/arch/arm/include/asm/xenomai/syscall.h b/kernel/cobalt/arch/arm/include/asm/xenomai/syscall.h
index 92afe8d9d..baa352181 100644
--- a/kernel/cobalt/arch/arm/include/asm/xenomai/syscall.h
+++ b/kernel/cobalt/arch/arm/include/asm/xenomai/syscall.h
@@ -33,6 +33,11 @@
 #define __ARM_NR_ipipe	(__NR_SYSCALL_BASE + XENO_ARM_SYSCALL)
 #endif
 
+/*
+ * Cobalt syscall numbers can be fetched from ARM_ORIG_r0 with ARM_r7
+ * containing the Xenomai syscall marker, Linux syscalls directly from
+ * ARM_r7 (may require the OABI tweak).
+ */
 #define __xn_reg_sys(__regs)	((__regs)->ARM_ORIG_r0)
 /* In OABI_COMPAT mode, handle both OABI and EABI userspace syscalls */
 #ifdef CONFIG_OABI_COMPAT
@@ -46,11 +51,15 @@
 #define __xn_syscall(__regs)	(__xn_reg_sys(__regs) & ~__COBALT_SYSCALL_BIT)
 
 /*
- * Returns the syscall number depending on the handling core. Cobalt
- * syscall numbers can be fetched from ARM_ORIG_r0 with ARM_r7
- * containing the Xenomai syscall marker, Linux syscalls directly from
- * ARM_r7 (may require the OABI tweak).
+ * Root syscall number with predicate (valid only if
+ * !__xn_syscall_p(__regs)).
  */
+#define __xn_rootcall_p(__regs, __code)					\
+	({								\
+		*(__code) = __xn_abi_decode(__regs);			\
+		*(__code) < NR_syscalls || *(__code) >= __ARM_NR_BASE;	\
+	})
+	
 static inline long __xn_get_syscall_nr(struct pt_regs *regs)
 {
 	return __xn_syscall_p(regs) ? __xn_reg_sys(regs) : __xn_abi_decode(regs);
diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c
index 68700a336..058a8282b 100644
--- a/kernel/cobalt/posix/syscall.c
+++ b/kernel/cobalt/posix/syscall.c
@@ -666,10 +666,6 @@ ret_handled:
 	return KEVENT_STOP;
 
 linux_syscall:
-	code = __xn_get_syscall_nr(regs);
-	if (code >= NR_syscalls)
-		goto bad_syscall;
-
 	if (xnsched_root_p())
 		/*
 		 * The call originates from the Linux domain, either
@@ -679,6 +675,9 @@ linux_syscall:
 		 */
 		return KEVENT_PROPAGATE;
 
+	if (!__xn_rootcall_p(regs, &code))
+		goto bad_syscall;
+
 	/*
 	 * We know this is a Cobalt thread since it runs over the head
 	 * domain, however the current syscall should be handled by

-- 
Philippe.



More information about the Xenomai mailing list