lkml.org 
[lkml]   [2007]   [Jun]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[patch 4/6] sys_indirect RFC - compat code for sys_indirect and compat_call_syscall for x86-64
    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 <davidel@xmailserver.org>


    - 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 majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-06-29 23:53    [W:0.024 / U:0.368 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site