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
|
/*
* Copyright (c) 2021 The strace developers.
* All rights reserved.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "defs.h"
#include "list.h"
#include "poke.h"
static struct list_item *poke_data_vec;
static size_t poke_data_vec_capacity; /* size of the arena */
static size_t poke_data_vec_size; /* size of the used arena */
static void
expand_poke_data_vec(void)
{
const size_t old_capacity = poke_data_vec_capacity;
poke_data_vec = xgrowarray(poke_data_vec, &poke_data_vec_capacity,
sizeof(*poke_data_vec));
memset(poke_data_vec + old_capacity, 0,
(poke_data_vec_capacity - old_capacity)
* sizeof(*poke_data_vec));
}
uint16_t
alloc_poke_data(void)
{
const uint16_t rval = poke_data_vec_size;
if (rval < poke_data_vec_size)
error_func_msg_and_die("poke index overflow");
if (poke_data_vec_size == poke_data_vec_capacity)
expand_poke_data_vec();
poke_data_vec_size++;
list_init(&poke_data_vec[rval]);
return rval;
}
bool
poke_add(uint16_t poke_idx, struct poke_payload *poke)
{
struct poke_payload *i;
list_foreach(i, &poke_data_vec[poke_idx], l)
if ((i->is_enter == poke->is_enter) &&
(i->arg_no == poke->arg_no))
/* duplicate */
return 1;
list_insert(&poke_data_vec[poke_idx], &poke->l);
return 0;
}
void
poke_tcb(struct tcb *tcp, uint16_t poke_idx, bool is_enter)
{
if (poke_idx >= poke_data_vec_size)
error_func_msg_and_die("poke_idx >= poke_data_vec_size");
debug_func_msg("poking pid %d on %s",
tcp->pid, is_enter ? "enter" : "exit");
bool poked = false;
struct poke_payload *i;
list_foreach(i, &poke_data_vec[poke_idx], l) {
if (i->is_enter != is_enter)
continue;
if (n_args(tcp) < i->arg_no) {
error_func_msg("Failed to tamper with process %d:"
" requested to tamper with argument #%u,"
" but system call '%s' has only %u arguments",
tcp->pid, i->arg_no,
tcp_sysent(tcp)->sys_name,
n_args(tcp));
continue;
}
unsigned int nwritten = upoken(tcp, tcp->u_arg[i->arg_no - 1],
i->data_len, i->data);
if (!nwritten)
error_func_msg("Failed to tamper with process %d:"
" couldn't poke",
tcp->pid);
else
poked = true;
}
if (poked)
tcp->flags |= TCB_TAMPERED_POKED;
}
|