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, ¶ms[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]