prctl.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * trace/beauty/prctl.c
  3. *
  4. * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
  5. *
  6. * Released under the GPL v2. (and only v2, not any later version)
  7. */
  8. #include "trace/beauty/beauty.h"
  9. #include <linux/kernel.h>
  10. #include <uapi/linux/prctl.h>
  11. #include "trace/beauty/generated/prctl_option_array.c"
  12. static size_t prctl__scnprintf_option(int option, char *bf, size_t size)
  13. {
  14. static DEFINE_STRARRAY(prctl_options);
  15. return strarray__scnprintf(&strarray__prctl_options, bf, size, "%d", option);
  16. }
  17. static size_t prctl__scnprintf_set_mm(int option, char *bf, size_t size)
  18. {
  19. static DEFINE_STRARRAY(prctl_set_mm_options);
  20. return strarray__scnprintf(&strarray__prctl_set_mm_options, bf, size, "%d", option);
  21. }
  22. size_t syscall_arg__scnprintf_prctl_arg2(char *bf, size_t size, struct syscall_arg *arg)
  23. {
  24. int option = syscall_arg__val(arg, 0);
  25. if (option == PR_SET_MM)
  26. return prctl__scnprintf_set_mm(arg->val, bf, size);
  27. /*
  28. * We still don't grab the contents of pointers on entry or exit,
  29. * so just print them as hex numbers
  30. */
  31. if (option == PR_SET_NAME)
  32. return syscall_arg__scnprintf_hex(bf, size, arg);
  33. return syscall_arg__scnprintf_long(bf, size, arg);
  34. }
  35. size_t syscall_arg__scnprintf_prctl_arg3(char *bf, size_t size, struct syscall_arg *arg)
  36. {
  37. int option = syscall_arg__val(arg, 0);
  38. if (option == PR_SET_MM)
  39. return syscall_arg__scnprintf_hex(bf, size, arg);
  40. return syscall_arg__scnprintf_long(bf, size, arg);
  41. }
  42. size_t syscall_arg__scnprintf_prctl_option(char *bf, size_t size, struct syscall_arg *arg)
  43. {
  44. unsigned long option = arg->val;
  45. enum {
  46. SPO_ARG2 = (1 << 1),
  47. SPO_ARG3 = (1 << 2),
  48. SPO_ARG4 = (1 << 3),
  49. SPO_ARG5 = (1 << 4),
  50. SPO_ARG6 = (1 << 5),
  51. };
  52. const u8 all_but2 = SPO_ARG3 | SPO_ARG4 | SPO_ARG5 | SPO_ARG6;
  53. const u8 all = SPO_ARG2 | all_but2;
  54. const u8 masks[] = {
  55. [PR_GET_DUMPABLE] = all,
  56. [PR_SET_DUMPABLE] = all_but2,
  57. [PR_SET_NAME] = all_but2,
  58. [PR_GET_CHILD_SUBREAPER] = all_but2,
  59. [PR_SET_CHILD_SUBREAPER] = all_but2,
  60. [PR_GET_SECUREBITS] = all,
  61. [PR_SET_SECUREBITS] = all_but2,
  62. [PR_SET_MM] = SPO_ARG4 | SPO_ARG5 | SPO_ARG6,
  63. [PR_GET_PDEATHSIG] = all,
  64. [PR_SET_PDEATHSIG] = all_but2,
  65. };
  66. if (option < ARRAY_SIZE(masks))
  67. arg->mask |= masks[option];
  68. return prctl__scnprintf_option(option, bf, size);
  69. }