(root)/
strace-6.5/
src/
poke.c
       1  /*
       2   * Copyright (c) 2021 The strace developers.
       3   * All rights reserved.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   */
       7  
       8  #include "defs.h"
       9  #include "list.h"
      10  #include "poke.h"
      11  
      12  static struct list_item *poke_data_vec;
      13  static size_t poke_data_vec_capacity; /* size of the arena */
      14  static size_t poke_data_vec_size;     /* size of the used arena */
      15  
      16  static void
      17  expand_poke_data_vec(void)
      18  {
      19  	const size_t old_capacity = poke_data_vec_capacity;
      20  	poke_data_vec = xgrowarray(poke_data_vec, &poke_data_vec_capacity,
      21  				    sizeof(*poke_data_vec));
      22  	memset(poke_data_vec + old_capacity, 0,
      23  	       (poke_data_vec_capacity - old_capacity)
      24  	       * sizeof(*poke_data_vec));
      25  }
      26  
      27  uint16_t
      28  alloc_poke_data(void)
      29  {
      30  	const uint16_t rval = poke_data_vec_size;
      31  
      32  	if (rval < poke_data_vec_size)
      33  		error_func_msg_and_die("poke index overflow");
      34  
      35  	if (poke_data_vec_size == poke_data_vec_capacity)
      36  		expand_poke_data_vec();
      37  
      38  	poke_data_vec_size++;
      39  
      40  	list_init(&poke_data_vec[rval]);
      41  	return rval;
      42  }
      43  
      44  bool
      45  poke_add(uint16_t poke_idx, struct poke_payload *poke)
      46  {
      47  	struct poke_payload *i;
      48  	list_foreach(i, &poke_data_vec[poke_idx], l)
      49  		if ((i->is_enter == poke->is_enter) &&
      50  		    (i->arg_no == poke->arg_no))
      51  			/* duplicate */
      52  			return 1;
      53  
      54  	list_insert(&poke_data_vec[poke_idx], &poke->l);
      55  	return 0;
      56  }
      57  
      58  void
      59  poke_tcb(struct tcb *tcp, uint16_t poke_idx, bool is_enter)
      60  {
      61  	if (poke_idx >= poke_data_vec_size)
      62  		error_func_msg_and_die("poke_idx >= poke_data_vec_size");
      63  
      64  	debug_func_msg("poking pid %d on %s",
      65  		       tcp->pid, is_enter ? "enter" : "exit");
      66  
      67  	bool poked = false;
      68  	struct poke_payload *i;
      69  	list_foreach(i, &poke_data_vec[poke_idx], l) {
      70  		if (i->is_enter != is_enter)
      71  			continue;
      72  		if (n_args(tcp) < i->arg_no) {
      73  			error_func_msg("Failed to tamper with process %d:"
      74  				       " requested to tamper with argument #%u,"
      75  				       " but system call '%s' has only %u arguments",
      76  				       tcp->pid, i->arg_no,
      77  				       tcp_sysent(tcp)->sys_name,
      78  				       n_args(tcp));
      79  			continue;
      80  		}
      81  		unsigned int nwritten = upoken(tcp, tcp->u_arg[i->arg_no - 1],
      82  					       i->data_len, i->data);
      83  		if (!nwritten)
      84  			error_func_msg("Failed to tamper with process %d:"
      85  				       " couldn't poke",
      86  				       tcp->pid);
      87  		else
      88  			poked = true;
      89  	}
      90  
      91  	if (poked)
      92  		tcp->flags |= TCB_TAMPERED_POKED;
      93  }