prctl.c 2.3 KB

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