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.

file_handle.c 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
  3. * Copyright (c) 2015-2019 The strace developers.
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: LGPL-2.1-or-later
  7. */
  8. #include "defs.h"
  9. #include "xlat/name_to_handle_at_flags.h"
  10. #ifndef MAX_HANDLE_SZ
  11. # define MAX_HANDLE_SZ 128
  12. #endif
  13. typedef struct {
  14. unsigned int handle_bytes;
  15. int handle_type;
  16. } file_handle_header;
  17. SYS_FUNC(name_to_handle_at)
  18. {
  19. file_handle_header h;
  20. const kernel_ulong_t addr = tcp->u_arg[2];
  21. if (entering(tcp)) {
  22. /* dirfd */
  23. print_dirfd(tcp, tcp->u_arg[0]);
  24. tprints(", ");
  25. /* pathname */
  26. printpath(tcp, tcp->u_arg[1]);
  27. tprints(", ");
  28. /* handle */
  29. if (umove_or_printaddr(tcp, addr, &h)) {
  30. tprints(", ");
  31. /* mount_id */
  32. printaddr(tcp->u_arg[3]);
  33. tprints(", ");
  34. /* flags */
  35. printflags(name_to_handle_at_flags, tcp->u_arg[4],
  36. "AT_???");
  37. return RVAL_DECODED;
  38. }
  39. tprintf("{handle_bytes=%u", h.handle_bytes);
  40. set_tcb_priv_ulong(tcp, h.handle_bytes);
  41. return 0;
  42. } else {
  43. unsigned int i = get_tcb_priv_ulong(tcp);
  44. if ((!syserror(tcp) || EOVERFLOW == tcp->u_error)
  45. && !umove(tcp, addr, &h)) {
  46. unsigned char f_handle[MAX_HANDLE_SZ];
  47. if (i != h.handle_bytes)
  48. tprintf(" => %u", h.handle_bytes);
  49. if (!syserror(tcp)) {
  50. tprintf(", handle_type=%d", h.handle_type);
  51. if (h.handle_bytes > MAX_HANDLE_SZ)
  52. h.handle_bytes = MAX_HANDLE_SZ;
  53. if (!umoven(tcp, addr + sizeof(h), h.handle_bytes,
  54. f_handle)) {
  55. tprints(", f_handle=0x");
  56. for (i = 0; i < h.handle_bytes; ++i)
  57. tprintf("%02x", f_handle[i]);
  58. }
  59. }
  60. }
  61. tprints("}, ");
  62. /* mount_id */
  63. printnum_int(tcp, tcp->u_arg[3], "%d");
  64. tprints(", ");
  65. /* flags */
  66. printflags(name_to_handle_at_flags, tcp->u_arg[4], "AT_???");
  67. }
  68. return 0;
  69. }
  70. SYS_FUNC(open_by_handle_at)
  71. {
  72. file_handle_header h;
  73. const kernel_ulong_t addr = tcp->u_arg[1];
  74. /* mount_fd */
  75. printfd(tcp, tcp->u_arg[0]);
  76. tprints(", ");
  77. /* handle */
  78. if (!umove_or_printaddr(tcp, addr, &h)) {
  79. unsigned char f_handle[MAX_HANDLE_SZ];
  80. tprintf("{handle_bytes=%u, handle_type=%d",
  81. h.handle_bytes, h.handle_type);
  82. if (h.handle_bytes > MAX_HANDLE_SZ)
  83. h.handle_bytes = MAX_HANDLE_SZ;
  84. if (!umoven(tcp, addr + sizeof(h), h.handle_bytes, &f_handle)) {
  85. unsigned int i;
  86. tprints(", f_handle=0x");
  87. for (i = 0; i < h.handle_bytes; ++i)
  88. tprintf("%02x", f_handle[i]);
  89. }
  90. tprints("}");
  91. }
  92. tprints(", ");
  93. /* flags */
  94. tprint_open_modes(tcp->u_arg[2]);
  95. return RVAL_DECODED;
  96. }