[patch 4/6] sys_indirect RFC - compat code for sys_indirect and compat_call_syscall for x86-64

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is the compat code necessary for sys_indirect(). Since the data
structure passed down to sys_indirect() is compat-free, this is the
only processing needed.
A required compat_call_syscall() has been added to the x86-64 arch.



Signed-off-by: Davide Libenzi <[email protected]>


- Davide



---
 arch/x86_64/ia32/ia32entry.S |   18 +++++++++++++++++
 include/asm-x86_64/unistd.h  |    1 
 kernel/compat.c              |   44 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+)

Index: linux-2.6.mod/kernel/compat.c
===================================================================
--- linux-2.6.mod.orig/kernel/compat.c	2007-06-29 12:12:41.000000000 -0700
+++ linux-2.6.mod/kernel/compat.c	2007-06-29 12:13:46.000000000 -0700
@@ -23,6 +23,8 @@
 #include <linux/timex.h>
 #include <linux/migrate.h>
 #include <linux/posix-timers.h>
+#include <linux/fsalloc.h>
+#include <linux/indirect.h>
 
 #include <asm/uaccess.h>
 
@@ -1082,3 +1084,45 @@
 	return 0;
 }
 
+asmlinkage long compat_sys_indirect(unsigned int nr,
+				    const __u32 __user *ctxs, unsigned int nctxs,
+				    const __u32 __user *params)
+{
+	unsigned int i;
+	long res;
+	u32 tmp;
+	struct indirect_op *iops;
+	const struct indirect_ctx __user * __user *uctxs;
+	unsigned long kparams[6];
+	struct fsa_context ator;
+	char ator_cache[128];
+
+	if (!indirect_call_ok(nr) || nctxs >= INT_MAX / sizeof(__u32))
+		return -EINVAL;
+	if (!access_ok(VERIFY_READ, params, 6 * sizeof(u32)) ||
+	    !access_ok(VERIFY_READ, ctxs, nctxs * sizeof(u32)))
+		return -EFAULT;
+	uctxs = compat_alloc_user_space(nctxs * sizeof(void *));
+	for (i = 0, res = 0; !res && i < nctxs; i++) {
+		res |= __get_user(tmp, &ctxs[i]);
+		res |= __put_user((unsigned long) tmp, &uctxs[i]);
+	}
+	if (res)
+		return -EFAULT;
+	for (i = 0, res = 0; i < 6; i++) {
+		res |= __get_user(tmp, &params[i]);
+		kparams[i] = tmp;
+	}
+	if (res)
+		return -EFAULT;
+	fsa_init(&ator, ator_cache, sizeof(ator_cache));
+	res = indirect_set_context(&ator, uctxs, nctxs, &iops);
+	if (likely(res == 0)) {
+		res = compat_call_syscall(nr, kparams);
+		indirect_unset_context(iops);
+	}
+	fsa_cleanup(&ator);
+
+	return res;
+}
+
Index: linux-2.6.mod/include/asm-x86_64/unistd.h
===================================================================
--- linux-2.6.mod.orig/include/asm-x86_64/unistd.h	2007-06-29 12:12:48.000000000 -0700
+++ linux-2.6.mod/include/asm-x86_64/unistd.h	2007-06-29 12:57:58.000000000 -0700
@@ -670,6 +670,7 @@
 				struct sigaction __user *oact,
 				size_t sigsetsize);
 extern long call_syscall(unsigned int nr, const unsigned long *params);
+extern long compat_call_syscall(unsigned int nr, const unsigned long *params);
 
 static inline int indirect_call_ok(unsigned int nr)
 {
Index: linux-2.6.mod/arch/x86_64/ia32/ia32entry.S
===================================================================
--- linux-2.6.mod.orig/arch/x86_64/ia32/ia32entry.S	2007-06-29 12:12:41.000000000 -0700
+++ linux-2.6.mod/arch/x86_64/ia32/ia32entry.S	2007-06-29 12:57:58.000000000 -0700
@@ -392,6 +392,24 @@
 	CFI_ENDPROC
 END(ia32_ptregs_common)
 
+ENTRY(compat_call_syscall)
+	movq	$-ENOSYS, %rax
+	cmpl	$(IA32_NR_syscalls-1), %edi
+	ja	bad_sysc
+	mov	%edi, %eax
+	movq	%rsi, %r11
+	movq	(%r11), %rdi
+	movq	8(%r11), %rsi
+	movq	16(%r11), %rdx
+	movq	24(%r11), %rcx
+	movq	32(%r11), %r8
+	movq	40(%r11), %r9
+	call	*ia32_sys_call_table(,%rax,8)
+bad_sysc:
+	ret
+ENDPROC(compat_call_syscall)
+
+
 	.section .rodata,"a"
 	.align 8
 ia32_sys_call_table:

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux