Newer
Older
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
/*
Copyright 2018-2019, Barcelona Supercomputing Center (BSC), Spain
Copyright 2015-2019, Johannes Gutenberg Universitaet Mainz, Germany
This software was partially supported by the
EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu).
This software was partially supported by the
ADA-FS project under the SPPEXA project funded by the DFG.
SPDX-License-Identifier: MIT
*/
#include "client/intercept.hpp"
#include "client/preload.hpp"
#include "client/hooks.hpp"
#ifndef NDEBUG
#include "client/syscall_names.hpp"
#endif
#include <libsyscall_intercept_hook_point.h>
#include <syscall.h>
#include <errno.h>
#define NOT_HOOKED 1
#define HOOKED 0
static inline int hook(long syscall_number,
long arg0, long arg1, long arg2,
long arg3, long arg4, long arg5,
long *result)
{
switch (syscall_number) {
case SYS_open:
*result = hook_openat(AT_FDCWD,
reinterpret_cast<char*>(arg0),
static_cast<int>(arg1),
static_cast<mode_t>(arg2));
break;
case SYS_openat:
*result = hook_openat(static_cast<int>(arg0),
reinterpret_cast<const char*>(arg1),
static_cast<int>(arg2),
static_cast<mode_t>(arg3));
break;
case SYS_close:
*result = hook_close(static_cast<int>(arg0));
break;
case SYS_stat:
*result = hook_stat(reinterpret_cast<char*>(arg0),
reinterpret_cast<struct stat*>(arg1));
break;
case SYS_lstat:
*result = hook_lstat(reinterpret_cast<char*>(arg0),
reinterpret_cast<struct stat*>(arg1));
break;
case SYS_fstat:
*result = hook_fstat(static_cast<int>(arg0),
reinterpret_cast<struct stat*>(arg1));
break;
case SYS_newfstatat:
*result = hook_fstatat(static_cast<int>(arg0),
reinterpret_cast<const char*>(arg1),
reinterpret_cast<struct stat *>(arg2),
static_cast<int>(arg3));
break;
reinterpret_cast<void*>(arg1),
static_cast<size_t>(arg2));
break;
case SYS_pread64:
*result = hook_pread(static_cast<unsigned int>(arg0),
reinterpret_cast<char *>(arg1),
static_cast<size_t>(arg2),
static_cast<loff_t>(arg3));
break;
case SYS_pwrite64:
*result = hook_pwrite(static_cast<unsigned int>(arg0),
reinterpret_cast<const char *>(arg1),
static_cast<size_t>(arg2),
static_cast<loff_t>(arg3));
break;
*result = hook_write(static_cast<unsigned int>(arg0),
reinterpret_cast<const char *>(arg1),
case SYS_writev:
*result = hook_writev(static_cast<unsigned long>(arg0),
reinterpret_cast<const struct iovec *>(arg1),
static_cast<unsigned long>(arg2));
break;
case SYS_pwritev:
*result = hook_pwritev(static_cast<unsigned long>(arg0),
reinterpret_cast<const struct iovec *>(arg1),
static_cast<unsigned long>(arg2),
static_cast<unsigned long>(arg3),
static_cast<unsigned long>(arg4));
break;
*result = hook_unlinkat(AT_FDCWD,
reinterpret_cast<const char *>(arg0),
0);
break;
case SYS_unlinkat:
*result = hook_unlinkat(static_cast<int>(arg0),
reinterpret_cast<const char*>(arg1),
static_cast<int>(arg2));
case SYS_rmdir:
*result = hook_unlinkat(AT_FDCWD,
reinterpret_cast<const char *>(arg0),
AT_REMOVEDIR);
break;
case SYS_symlink:
*result = hook_symlinkat(reinterpret_cast<const char *>(arg0),
AT_FDCWD,
reinterpret_cast<const char *>(arg1));
break;
case SYS_symlinkat:
*result = hook_symlinkat(reinterpret_cast<const char *>(arg0),
static_cast<int>(arg1),
reinterpret_cast<const char *>(arg2));
break;
*result = hook_access(reinterpret_cast<const char*>(arg0),
case SYS_faccessat:
*result = hook_faccessat(static_cast<int>(arg0),
reinterpret_cast<const char*>(arg1),
static_cast<int>(arg2));
break;
case SYS_lseek:
*result = hook_lseek(static_cast<unsigned int>(arg0),
static_cast<off_t>(arg1),
static_cast<unsigned int>(arg2));
break;
case SYS_truncate:
*result = hook_truncate(reinterpret_cast<const char*>(arg0),
static_cast<long>(arg1));
break;
case SYS_ftruncate:
*result = hook_ftruncate(static_cast<unsigned int>(arg0),
static_cast<unsigned long>(arg1));
break;
case SYS_dup:
*result = hook_dup(static_cast<unsigned int>(arg0));
break;
case SYS_dup2:
*result = hook_dup2(static_cast<unsigned int>(arg0),
static_cast<unsigned int>(arg1));
break;
case SYS_dup3:
*result = hook_dup3(static_cast<unsigned int>(arg0),
static_cast<unsigned int>(arg1),
static_cast<int>(arg2));
break;
case SYS_getdents:
*result = hook_getdents(static_cast<unsigned int>(arg0),
reinterpret_cast<struct linux_dirent *>(arg1),
static_cast<unsigned int>(arg2));
break;
case SYS_mkdirat:
*result = hook_mkdirat(static_cast<unsigned int>(arg0),
reinterpret_cast<const char *>(arg1),
static_cast<mode_t>(arg2));
break;
case SYS_mkdir:
*result = hook_mkdirat(AT_FDCWD,
reinterpret_cast<const char *>(arg0),
static_cast<mode_t>(arg1));
break;
case SYS_chmod:
*result = hook_fchmodat(AT_FDCWD,
reinterpret_cast<char*>(arg0),
static_cast<mode_t>(arg1));
break;
case SYS_fchmod:
*result = hook_fchmod(static_cast<unsigned int>(arg0),
static_cast<mode_t>(arg1));
break;
case SYS_fchmodat:
*result = hook_fchmodat(static_cast<unsigned int>(arg0),
reinterpret_cast<char*>(arg1),
static_cast<mode_t>(arg2));
break;
case SYS_chdir:
*result = hook_chdir(reinterpret_cast<const char *>(arg0));
break;
case SYS_fchdir:
*result = hook_fchdir(static_cast<unsigned int>(arg0));
break;
case SYS_getcwd:
*result = hook_getcwd(reinterpret_cast<char *>(arg0),
static_cast<unsigned long>(arg1));
break;
case SYS_readlink:
*result = hook_readlinkat(AT_FDCWD,
reinterpret_cast<const char *>(arg0),
reinterpret_cast<char *>(arg1),
static_cast<int>(arg2));
break;
case SYS_readlinkat:
*result = hook_readlinkat(static_cast<int>(arg0),
reinterpret_cast<const char *>(arg1),
reinterpret_cast<char *>(arg2),
static_cast<int>(arg3));
break;
case SYS_fcntl:
*result = hook_fcntl(static_cast<unsigned int>(arg0),
static_cast<unsigned int>(arg1),
static_cast<unsigned long>(arg2));
break;
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
/*
* Ignore any other syscalls
* i.e.: pass them on to the kernel
* as would normally happen.
*/
#ifndef NDEBUG
CTX->log()->trace("Syscall [{}, {}] Passthrough", syscall_names[syscall_number], syscall_number);
#endif
return NOT_HOOKED;
}
#ifndef NDEBUG
CTX->log()->trace("Syscall [{}, {}] Intercepted", syscall_names[syscall_number], syscall_number);
#endif
return HOOKED;
}
static __thread bool guard_flag;
int
hook_guard_wrapper(long syscall_number,
long arg0, long arg1, long arg2,
long arg3, long arg4, long arg5,
long *syscall_return_value)
{
assert(CTX->interception_enabled());
if (guard_flag) {
return NOT_HOOKED;
}
int is_hooked;
guard_flag = true;
int oerrno = errno;
is_hooked = hook(syscall_number,
arg0, arg1, arg2, arg3, arg4, arg5,
syscall_return_value);
errno = oerrno;
guard_flag = false;
return is_hooked;
}
void start_interception() {
assert(CTX->interception_enabled());
#ifndef NDEBUG
CTX->log()->debug("Activating interception of syscalls");
#endif
// Set up the callback function pointer
intercept_hook_point = hook_guard_wrapper;
}
void stop_interception() {
assert(CTX->interception_enabled());
// Reset callback function pointer
intercept_hook_point = nullptr;
}