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.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
  3. * Copyright (c) 2015-2018 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. /* pathname */
  25. printpath(tcp, tcp->u_arg[1]);
  26. tprints(", ");
  27. /* handle */
  28. if (umove_or_printaddr(tcp, addr, &h)) {
  29. tprints(", ");
  30. /* mount_id */
  31. printaddr(tcp->u_arg[3]);
  32. tprints(", ");
  33. /* flags */
  34. printflags(name_to_handle_at_flags, tcp->u_arg[4],
  35. "AT_???");
  36. return RVAL_DECODED;
  37. }
  38. tprintf("{handle_bytes=%u", h.handle_bytes);
  39. set_tcb_priv_ulong(tcp, h.handle_bytes);
  40. return 0;
  41. } else {
  42. unsigned int i = get_tcb_priv_ulong(tcp);
  43. if ((!syserror(tcp) || EOVERFLOW == tcp->u_error)
  44. && !umove(tcp, addr, &h)) {
  45. unsigned char f_handle[MAX_HANDLE_SZ];
  46. if (i != h.handle_bytes)
  47. tprintf(" => %u", h.handle_bytes);
  48. if (!syserror(tcp)) {
  49. tprintf(", handle_type=%d", h.handle_type);
  50. if (h.handle_bytes > MAX_HANDLE_SZ)
  51. h.handle_bytes = MAX_HANDLE_SZ;
  52. if (!umoven(tcp, addr + sizeof(h), h.handle_bytes,
  53. f_handle)) {
  54. tprints(", f_handle=0x");
  55. for (i = 0; i < h.handle_bytes; ++i)
  56. tprintf("%02x", f_handle[i]);
  57. }
  58. }
  59. }
  60. tprints("}, ");
  61. /* mount_id */
  62. printnum_int(tcp, tcp->u_arg[3], "%d");
  63. tprints(", ");
  64. /* flags */
  65. printflags(name_to_handle_at_flags, tcp->u_arg[4], "AT_???");
  66. }
  67. return 0;
  68. }
  69. SYS_FUNC(open_by_handle_at)
  70. {
  71. file_handle_header h;
  72. const kernel_ulong_t addr = tcp->u_arg[1];
  73. /* mount_fd */
  74. printfd(tcp, tcp->u_arg[0]);
  75. tprints(", ");
  76. /* handle */
  77. if (!umove_or_printaddr(tcp, addr, &h)) {
  78. unsigned char f_handle[MAX_HANDLE_SZ];
  79. tprintf("{handle_bytes=%u, handle_type=%d",
  80. h.handle_bytes, h.handle_type);
  81. if (h.handle_bytes > MAX_HANDLE_SZ)
  82. h.handle_bytes = MAX_HANDLE_SZ;
  83. if (!umoven(tcp, addr + sizeof(h), h.handle_bytes, &f_handle)) {
  84. unsigned int i;
  85. tprints(", f_handle=0x");
  86. for (i = 0; i < h.handle_bytes; ++i)
  87. tprintf("%02x", f_handle[i]);
  88. }
  89. tprints("}");
  90. }
  91. tprints(", ");
  92. /* flags */
  93. tprint_open_modes(tcp->u_arg[2]);
  94. return RVAL_DECODED;
  95. }