Commit 828c365cc8b8d38c346fccb19fa80d28f2240831

Authored by Roland McGrath
Committed by Linus Torvalds
1 parent 64b1208d5b

tracehook: asm/syscall.h

This adds asm-generic/syscall.h, which documents what a real
asm-ARCH/syscall.h file should define.  This is not used yet, but will
provide all the machine-dependent details of examining a user system call
about to begin, in progress, or just ended.

Each arch should add an asm-ARCH/syscall.h that defines all the entry
points documented in asm-generic/syscall.h, as short inlines if possible.
This lets us write new tracing code that understands user system call
registers, without any new arch-specific work.

Signed-off-by: Roland McGrath <roland@redhat.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 143 additions and 1 deletions Side-by-side Diff

include/asm-generic/syscall.h
  1 +/*
  2 + * Access to user system call parameters and results
  3 + *
  4 + * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
  5 + *
  6 + * This copyrighted material is made available to anyone wishing to use,
  7 + * modify, copy, or redistribute it subject to the terms and conditions
  8 + * of the GNU General Public License v.2.
  9 + *
  10 + * This file is a stub providing documentation for what functions
  11 + * asm-ARCH/syscall.h files need to define. Most arch definitions
  12 + * will be simple inlines.
  13 + *
  14 + * All of these functions expect to be called with no locks,
  15 + * and only when the caller is sure that the task of interest
  16 + * cannot return to user mode while we are looking at it.
  17 + */
  18 +
  19 +#ifndef _ASM_SYSCALL_H
  20 +#define _ASM_SYSCALL_H 1
  21 +
  22 +struct task_struct;
  23 +struct pt_regs;
  24 +
  25 +/**
  26 + * syscall_get_nr - find what system call a task is executing
  27 + * @task: task of interest, must be blocked
  28 + * @regs: task_pt_regs() of @task
  29 + *
  30 + * If @task is executing a system call or is at system call
  31 + * tracing about to attempt one, returns the system call number.
  32 + * If @task is not executing a system call, i.e. it's blocked
  33 + * inside the kernel for a fault or signal, returns -1.
  34 + *
  35 + * It's only valid to call this when @task is known to be blocked.
  36 + */
  37 +long syscall_get_nr(struct task_struct *task, struct pt_regs *regs);
  38 +
  39 +/**
  40 + * syscall_rollback - roll back registers after an aborted system call
  41 + * @task: task of interest, must be in system call exit tracing
  42 + * @regs: task_pt_regs() of @task
  43 + *
  44 + * It's only valid to call this when @task is stopped for system
  45 + * call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT),
  46 + * after tracehook_report_syscall_entry() returned nonzero to prevent
  47 + * the system call from taking place.
  48 + *
  49 + * This rolls back the register state in @regs so it's as if the
  50 + * system call instruction was a no-op. The registers containing
  51 + * the system call number and arguments are as they were before the
  52 + * system call instruction. This may not be the same as what the
  53 + * register state looked like at system call entry tracing.
  54 + */
  55 +void syscall_rollback(struct task_struct *task, struct pt_regs *regs);
  56 +
  57 +/**
  58 + * syscall_get_error - check result of traced system call
  59 + * @task: task of interest, must be blocked
  60 + * @regs: task_pt_regs() of @task
  61 + *
  62 + * Returns 0 if the system call succeeded, or -ERRORCODE if it failed.
  63 + *
  64 + * It's only valid to call this when @task is stopped for tracing on exit
  65 + * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
  66 + */
  67 +long syscall_get_error(struct task_struct *task, struct pt_regs *regs);
  68 +
  69 +/**
  70 + * syscall_get_return_value - get the return value of a traced system call
  71 + * @task: task of interest, must be blocked
  72 + * @regs: task_pt_regs() of @task
  73 + *
  74 + * Returns the return value of the successful system call.
  75 + * This value is meaningless if syscall_get_error() returned nonzero.
  76 + *
  77 + * It's only valid to call this when @task is stopped for tracing on exit
  78 + * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
  79 + */
  80 +long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs);
  81 +
  82 +/**
  83 + * syscall_set_return_value - change the return value of a traced system call
  84 + * @task: task of interest, must be blocked
  85 + * @regs: task_pt_regs() of @task
  86 + * @error: negative error code, or zero to indicate success
  87 + * @val: user return value if @error is zero
  88 + *
  89 + * This changes the results of the system call that user mode will see.
  90 + * If @error is zero, the user sees a successful system call with a
  91 + * return value of @val. If @error is nonzero, it's a negated errno
  92 + * code; the user sees a failed system call with this errno code.
  93 + *
  94 + * It's only valid to call this when @task is stopped for tracing on exit
  95 + * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
  96 + */
  97 +void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
  98 + int error, long val);
  99 +
  100 +/**
  101 + * syscall_get_arguments - extract system call parameter values
  102 + * @task: task of interest, must be blocked
  103 + * @regs: task_pt_regs() of @task
  104 + * @i: argument index [0,5]
  105 + * @n: number of arguments; n+i must be [1,6].
  106 + * @args: array filled with argument values
  107 + *
  108 + * Fetches @n arguments to the system call starting with the @i'th argument
  109 + * (from 0 through 5). Argument @i is stored in @args[0], and so on.
  110 + * An arch inline version is probably optimal when @i and @n are constants.
  111 + *
  112 + * It's only valid to call this when @task is stopped for tracing on
  113 + * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
  114 + * It's invalid to call this with @i + @n > 6; we only support system calls
  115 + * taking up to 6 arguments.
  116 + */
  117 +void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
  118 + unsigned int i, unsigned int n, unsigned long *args);
  119 +
  120 +/**
  121 + * syscall_set_arguments - change system call parameter value
  122 + * @task: task of interest, must be in system call entry tracing
  123 + * @regs: task_pt_regs() of @task
  124 + * @i: argument index [0,5]
  125 + * @n: number of arguments; n+i must be [1,6].
  126 + * @args: array of argument values to store
  127 + *
  128 + * Changes @n arguments to the system call starting with the @i'th argument.
  129 + * @n'th argument to @val. Argument @i gets value @args[0], and so on.
  130 + * An arch inline version is probably optimal when @i and @n are constants.
  131 + *
  132 + * It's only valid to call this when @task is stopped for tracing on
  133 + * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
  134 + * It's invalid to call this with @i + @n > 6; we only support system calls
  135 + * taking up to 6 arguments.
  136 + */
  137 +void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
  138 + unsigned int i, unsigned int n,
  139 + const unsigned long *args);
  140 +
  141 +#endif /* _ASM_SYSCALL_H */
include/linux/tracehook.h
... ... @@ -103,7 +103,8 @@
103 103 * the system call. That must prevent normal entry so no system call is
104 104 * made. If @task ever returns to user mode after this, its register state
105 105 * is unspecified, but should be something harmless like an %ENOSYS error
106   - * return.
  106 + * return. It should preserve enough information so that syscall_rollback()
  107 + * can work (see asm-generic/syscall.h).
107 108 *
108 109 * Called without locks, just after entering kernel mode.
109 110 */