Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ucopy.c 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /*
  2. * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
  3. * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
  4. * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
  5. * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
  6. * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  7. * Linux for s390 port by D.J. Barrow
  8. * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
  9. * Copyright (c) 1999-2019 The strace developers.
  10. * All rights reserved.
  11. *
  12. * SPDX-License-Identifier: LGPL-2.1-or-later
  13. */
  14. #include "defs.h"
  15. #include <sys/uio.h>
  16. #include "scno.h"
  17. #include "ptrace.h"
  18. static bool process_vm_readv_not_supported;
  19. #ifndef HAVE_PROCESS_VM_READV
  20. /*
  21. * Need to do this since process_vm_readv() is not yet available in libc.
  22. * When libc is updated, only "static bool process_vm_readv_not_supported"
  23. * line remains.
  24. * The name is different to avoid potential collision with OS headers.
  25. */
  26. static ssize_t strace_process_vm_readv(pid_t pid,
  27. const struct iovec *lvec,
  28. unsigned long liovcnt,
  29. const struct iovec *rvec,
  30. unsigned long riovcnt,
  31. unsigned long flags)
  32. {
  33. return syscall(__NR_process_vm_readv,
  34. (long) pid, lvec, liovcnt, rvec, riovcnt, flags);
  35. }
  36. # define process_vm_readv strace_process_vm_readv
  37. #endif /* !HAVE_PROCESS_VM_READV */
  38. static ssize_t
  39. process_read_mem(const pid_t pid, void *const laddr,
  40. void *const raddr, const size_t len)
  41. {
  42. const struct iovec local = {
  43. .iov_base = laddr,
  44. .iov_len = len
  45. };
  46. const struct iovec remote = {
  47. .iov_base = raddr,
  48. .iov_len = len
  49. };
  50. const ssize_t rc = process_vm_readv(pid, &local, 1, &remote, 1, 0);
  51. if (rc < 0 && errno == ENOSYS)
  52. process_vm_readv_not_supported = true;
  53. return rc;
  54. }
  55. static int cached_idx = -1;
  56. static unsigned long cached_raddr[4];
  57. void
  58. invalidate_umove_cache(void)
  59. {
  60. cached_idx = -1;
  61. }
  62. static int
  63. get_next_unused_idx(void)
  64. {
  65. return (cached_idx + 1) % ARRAY_SIZE(cached_raddr);
  66. }
  67. static int
  68. lookup_cached_raddr_idx(const unsigned long raddr)
  69. {
  70. if (cached_idx >= 0) {
  71. for (int i = cached_idx; i >= 0; --i)
  72. if (raddr == cached_raddr[i])
  73. return i;
  74. for (int i = (int) ARRAY_SIZE(cached_raddr) - 1;
  75. i > cached_idx; --i)
  76. if (raddr == cached_raddr[i])
  77. return i;
  78. }
  79. return -1;
  80. }
  81. static void
  82. set_cached_raddr_idx(const unsigned long raddr, const int idx)
  83. {
  84. if (cached_idx < 0)
  85. memset(cached_raddr, 0, sizeof(cached_raddr));
  86. cached_raddr[idx] = raddr;
  87. cached_idx = idx;
  88. }
  89. static ssize_t
  90. vm_read_mem(const pid_t pid, void *laddr,
  91. const kernel_ulong_t kraddr, size_t len)
  92. {
  93. if (!len)
  94. return len;
  95. unsigned long taddr = kraddr;
  96. #if SIZEOF_LONG < SIZEOF_KERNEL_LONG_T
  97. if (kraddr != (kernel_ulong_t) taddr) {
  98. errno = EIO;
  99. return -1;
  100. }
  101. #endif
  102. const size_t page_size = get_pagesize();
  103. const size_t page_mask = page_size - 1;
  104. unsigned long page_start = taddr & ~page_mask;
  105. const unsigned long page_after_last =
  106. (taddr + len + page_mask) & ~page_mask;
  107. if (!page_start ||
  108. page_after_last < page_start ||
  109. page_after_last - page_start > ARRAY_SIZE(cached_raddr) * page_size)
  110. return process_read_mem(pid, laddr, (void *) taddr, len);
  111. size_t total_read = 0;
  112. for (;;) {
  113. static char *buf[ARRAY_SIZE(cached_raddr)];
  114. int idx = lookup_cached_raddr_idx(page_start);
  115. if (idx == -1) {
  116. idx = get_next_unused_idx();
  117. if (!buf[idx])
  118. buf[idx] = xmalloc(page_size);
  119. const ssize_t rc =
  120. process_read_mem(pid, buf[idx],
  121. (void *) page_start, page_size);
  122. if (rc < 0)
  123. return total_read ? (ssize_t) total_read : rc;
  124. set_cached_raddr_idx(page_start, idx);
  125. }
  126. const unsigned long offset = taddr - page_start;
  127. size_t copy_len, next_len;
  128. if (len <= page_size - offset) {
  129. copy_len = len;
  130. next_len = 0;
  131. } else {
  132. copy_len = page_size - offset;
  133. next_len = len - copy_len;
  134. }
  135. memcpy(laddr, buf[idx] + offset, copy_len);
  136. total_read += copy_len;
  137. if (!next_len)
  138. break;
  139. len = next_len;
  140. laddr += copy_len;
  141. page_start += page_size;
  142. taddr = page_start;
  143. }
  144. return total_read;
  145. }
  146. static bool
  147. tracee_addr_is_invalid(kernel_ulong_t addr)
  148. {
  149. return
  150. #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
  151. current_wordsize < sizeof(addr) && addr & ~(kernel_ulong_t) -1U;
  152. #else
  153. false;
  154. #endif
  155. }
  156. /* legacy method of copying from tracee */
  157. static int
  158. umoven_peekdata(const int pid, kernel_ulong_t addr, unsigned int len,
  159. void *laddr)
  160. {
  161. unsigned int nread = 0;
  162. unsigned int residue = addr & (sizeof(long) - 1);
  163. while (len) {
  164. addr &= -sizeof(long); /* aligned address */
  165. errno = 0;
  166. union {
  167. long val;
  168. char x[sizeof(long)];
  169. } u = { .val = ptrace(PTRACE_PEEKDATA, pid, addr, 0) };
  170. switch (errno) {
  171. case 0:
  172. break;
  173. case ESRCH: case EINVAL:
  174. /* these could be seen if the process is gone */
  175. return -1;
  176. case EFAULT: case EIO: case EPERM:
  177. /* address space is inaccessible */
  178. if (nread) {
  179. perror_func_msg("short read (%u < %u)"
  180. " @0x%" PRI_klx,
  181. nread, nread + len,
  182. addr - nread);
  183. }
  184. return -1;
  185. default:
  186. /* all the rest is strange and should be reported */
  187. perror_func_msg("pid:%d @0x%" PRI_klx,
  188. pid, addr);
  189. return -1;
  190. }
  191. unsigned int m = MIN(sizeof(long) - residue, len);
  192. memcpy(laddr, &u.x[residue], m);
  193. residue = 0;
  194. addr += sizeof(long);
  195. laddr += m;
  196. nread += m;
  197. len -= m;
  198. }
  199. return 0;
  200. }
  201. /*
  202. * Copy `len' bytes of data from process `pid'
  203. * at address `addr' to our space at `our_addr'.
  204. */
  205. int
  206. umoven(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
  207. void *const our_addr)
  208. {
  209. if (tracee_addr_is_invalid(addr))
  210. return -1;
  211. const int pid = tcp->pid;
  212. if (process_vm_readv_not_supported)
  213. return umoven_peekdata(pid, addr, len, our_addr);
  214. int r = vm_read_mem(pid, our_addr, addr, len);
  215. if ((unsigned int) r == len)
  216. return 0;
  217. if (r >= 0) {
  218. error_func_msg("short read (%u < %u) @0x%" PRI_klx,
  219. (unsigned int) r, len, addr);
  220. return -1;
  221. }
  222. switch (errno) {
  223. case ENOSYS:
  224. case EPERM:
  225. /* try PTRACE_PEEKDATA */
  226. return umoven_peekdata(pid, addr, len, our_addr);
  227. case ESRCH:
  228. /* the process is gone */
  229. return -1;
  230. case EFAULT: case EIO:
  231. /* address space is inaccessible */
  232. return -1;
  233. default:
  234. /* all the rest is strange and should be reported */
  235. perror_func_msg("pid:%d @0x%" PRI_klx, pid, addr);
  236. return -1;
  237. }
  238. }
  239. /*
  240. * Like umoven_peekdata but make the additional effort of looking
  241. * for a terminating zero byte.
  242. */
  243. static int
  244. umovestr_peekdata(const int pid, kernel_ulong_t addr, unsigned int len,
  245. void *laddr)
  246. {
  247. unsigned int nread = 0;
  248. unsigned int residue = addr & (sizeof(long) - 1);
  249. void *const orig_addr = laddr;
  250. while (len) {
  251. addr &= -sizeof(long); /* aligned address */
  252. errno = 0;
  253. union {
  254. unsigned long val;
  255. char x[sizeof(long)];
  256. } u = { .val = ptrace(PTRACE_PEEKDATA, pid, addr, 0) };
  257. switch (errno) {
  258. case 0:
  259. break;
  260. case ESRCH: case EINVAL:
  261. /* these could be seen if the process is gone */
  262. return -1;
  263. case EFAULT: case EIO: case EPERM:
  264. /* address space is inaccessible */
  265. if (nread) {
  266. perror_func_msg("short read (%d < %d)"
  267. " @0x%" PRI_klx,
  268. nread, nread + len,
  269. addr - nread);
  270. }
  271. return -1;
  272. default:
  273. /* all the rest is strange and should be reported */
  274. perror_func_msg("pid:%d @0x%" PRI_klx,
  275. pid, addr);
  276. return -1;
  277. }
  278. unsigned int m = MIN(sizeof(long) - residue, len);
  279. memcpy(laddr, &u.x[residue], m);
  280. while (residue < sizeof(long))
  281. if (u.x[residue++] == '\0')
  282. return (laddr - orig_addr) + residue;
  283. residue = 0;
  284. addr += sizeof(long);
  285. laddr += m;
  286. nread += m;
  287. len -= m;
  288. }
  289. return 0;
  290. }
  291. /*
  292. * Like `umove' but make the additional effort of looking
  293. * for a terminating zero byte.
  294. *
  295. * Returns < 0 on error, strlen + 1 if NUL was seen,
  296. * else 0 if len bytes were read but no NUL byte seen.
  297. *
  298. * Note: there is no guarantee we won't overwrite some bytes
  299. * in laddr[] _after_ terminating NUL (but, of course,
  300. * we never write past laddr[len-1]).
  301. */
  302. int
  303. umovestr(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
  304. char *laddr)
  305. {
  306. if (tracee_addr_is_invalid(addr))
  307. return -1;
  308. const int pid = tcp->pid;
  309. if (process_vm_readv_not_supported)
  310. return umovestr_peekdata(pid, addr, len, laddr);
  311. const size_t page_size = get_pagesize();
  312. const size_t page_mask = page_size - 1;
  313. unsigned int nread = 0;
  314. while (len) {
  315. /*
  316. * Don't cross pages, otherwise we can get EFAULT
  317. * and fail to notice that terminating NUL lies
  318. * in the existing (first) page.
  319. */
  320. unsigned int chunk_len = len > page_size ? page_size : len;
  321. unsigned int end_in_page = (addr + chunk_len) & page_mask;
  322. if (chunk_len > end_in_page) /* crosses to the next page */
  323. chunk_len -= end_in_page;
  324. int r = vm_read_mem(pid, laddr, addr, chunk_len);
  325. if (r > 0) {
  326. char *nul_addr = memchr(laddr, '\0', r);
  327. if (nul_addr)
  328. return (nul_addr - laddr) + 1;
  329. addr += r;
  330. laddr += r;
  331. nread += r;
  332. len -= r;
  333. continue;
  334. }
  335. switch (errno) {
  336. case ENOSYS:
  337. case EPERM:
  338. /* try PTRACE_PEEKDATA */
  339. if (!nread)
  340. return umovestr_peekdata(pid, addr,
  341. len, laddr);
  342. ATTRIBUTE_FALLTHROUGH;
  343. case EFAULT: case EIO:
  344. /* address space is inaccessible */
  345. if (nread)
  346. perror_func_msg("short read (%d < %d)"
  347. " @0x%" PRI_klx,
  348. nread, nread + len,
  349. addr - nread);
  350. return -1;
  351. case ESRCH:
  352. /* the process is gone */
  353. return -1;
  354. default:
  355. /* all the rest is strange and should be reported */
  356. perror_func_msg("pid:%d @0x%" PRI_klx, pid, addr);
  357. return -1;
  358. }
  359. }
  360. return 0;
  361. }