Skip to content

Commit 828c365

Browse files
Roland McGrathtorvalds
authored andcommitted
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 <[email protected]> Cc: Oleg Nesterov <[email protected]> Reviewed-by: Ingo Molnar <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 64b1208 commit 828c365

File tree

2 files changed

+143
-1
lines changed

2 files changed

+143
-1
lines changed

include/asm-generic/syscall.h

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ static inline void ptrace_report_syscall(struct pt_regs *regs)
103103
* the system call. That must prevent normal entry so no system call is
104104
* made. If @task ever returns to user mode after this, its register state
105105
* 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).
107108
*
108109
* Called without locks, just after entering kernel mode.
109110
*/

0 commit comments

Comments
 (0)