File: syscall.h

package info (click to toggle)
trinity 1.9%2Bgit20230109.87f1530-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,116 kB
  • sloc: ansic: 33,463; sh: 536; makefile: 163
file content (181 lines) | stat: -rw-r--r-- 3,787 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#pragma once

#include <time.h>
#include <sys/types.h>
#include "locks.h"
#include "types.h"
#include "utils.h"

#define PREBUFFER_LEN	4096 * 6
#define POSTBUFFER_LEN	128

#define MAX_NR_SYSCALL 1024

enum syscallstate {
	UNKNOWN,	/* new child */
	PREP,		/* doing sanitize */
	BEFORE,		/* about to do syscall */
	GOING_AWAY,	/* used when we don't expect to come back (execve for eg) */
	AFTER,		/* returned from doing syscall. */
};

struct syscallrecord {
	unsigned int nr;
	unsigned long a1;
	unsigned long a2;
	unsigned long a3;
	unsigned long a4;
	unsigned long a5;
	unsigned long a6;
	unsigned long retval;

	/* timestamp (written before the syscall, and updated afterwards. */
	struct timespec tp;

	int errno_post;	/* what errno was after the syscall. */

	bool do32bit;
	lock_t lock;
	enum syscallstate state;
	char prebuffer[PREBUFFER_LEN];
	char postbuffer[POSTBUFFER_LEN];
};

enum argtype {
	ARG_UNDEFINED,
	ARG_FD,
	ARG_LEN,
	ARG_ADDRESS,
	ARG_MODE_T,
	ARG_NON_NULL_ADDRESS,
	ARG_PID,
	ARG_RANGE,
	ARG_OP,
	ARG_LIST,
	ARG_CPU,
	ARG_PATHNAME,
	ARG_IOVEC,
	ARG_IOVECLEN,
	ARG_SOCKADDR,
	ARG_SOCKADDRLEN,
	ARG_MMAP,
	ARG_SOCKETINFO,
};

struct arglist {
	unsigned int num;
	unsigned long *values;
};

#define ARGLIST(vals)		\
{				\
	.num = ARRAY_SIZE(vals),\
	.values = vals,		\
}

#define NR_ERRNOS 133	// Number in /usr/include/asm-generic/errno.h

struct results {
	union {
		// ARG_FD.  -1 = Avoid. 0 = untested. 1 = Works.
		int fdmap[1024];
		// ARG_LEN
		unsigned int min, max;
	};
};

struct syscallentry {
	void (*sanitise)(struct syscallrecord *rec);
	void (*post)(struct syscallrecord *rec);
	int (*init)(void);
	char * (*decode)(struct syscallrecord *rec, unsigned int argnum);

	unsigned int number;
	unsigned int active_number;
	const char name[80];
	const unsigned int num_args;
	unsigned int flags;

	const enum argtype arg1type;
	const enum argtype arg2type;
	const enum argtype arg3type;
	const enum argtype arg4type;
	const enum argtype arg5type;
	const enum argtype arg6type;

	const char *arg1name;
	const char *arg2name;
	const char *arg3name;
	const char *arg4name;
	const char *arg5name;
	const char *arg6name;

	struct results results1;
	struct results results2;
	struct results results3;
	struct results results4;
	struct results results5;
	struct results results6;

	unsigned int successes, failures, attempted;
	unsigned int errnos[NR_ERRNOS];

	/* FIXME: At some point, if we grow more type specific parts here,
	 * it may be worth union-ising this
	 */

	/* ARG_RANGE */
	const unsigned int low1range, hi1range;
	const unsigned int low2range, hi2range;
	const unsigned int low3range, hi3range;
	const unsigned int low4range, hi4range;
	const unsigned int low5range, hi5range;
	const unsigned int low6range, hi6range;

	/* ARG_OP / ARG_LIST */
	const struct arglist arg1list;
	const struct arglist arg2list;
	const struct arglist arg3list;
	const struct arglist arg4list;
	const struct arglist arg5list;
	const struct arglist arg6list;

	const unsigned int group;
	const int rettype;
};

#define RET_BORING		-1
#define RET_NONE		0
#define RET_ZERO_SUCCESS	1
#define RET_FD			2
#define RET_KEY_SERIAL_T	3
#define RET_PID_T		4
#define RET_PATH		5
#define RET_NUM_BYTES		6
#define RET_GID_T		7
#define RET_UID_T		8

#define GROUP_NONE	0
#define GROUP_VM	1
#define GROUP_VFS	2

struct syscalltable {
	struct syscallentry *entry;
};

#define AVOID_SYSCALL		(1<<0)
#define NI_SYSCALL		(1<<1)
#define BORING			(1<<2)
#define ACTIVE			(1<<3)
#define TO_BE_DEACTIVATED	(1<<4)
#define NEED_ALARM		(1<<5)
#define EXTRA_FORK		(1<<6)
#define IGNORE_ENOSYS		(1<<7)
#define EXPENSIVE		(1<<8)

void do_syscall(struct syscallrecord *rec);
void handle_syscall_ret(struct syscallrecord *rec);

#define for_each_arg(_e, _i) \
	for (_i = 1; _i <= _e->num_args; _i++)