strict_rwx.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Module strict rwx
  4. *
  5. * Copyright (C) 2015 Rusty Russell
  6. */
  7. #include <linux/module.h>
  8. #include <linux/mm.h>
  9. #include <linux/vmalloc.h>
  10. #include <linux/set_memory.h>
  11. #include "internal.h"
  12. /*
  13. * LKM RO/NX protection: protect module's text/ro-data
  14. * from modification and any data from execution.
  15. *
  16. * General layout of module is:
  17. * [text] [read-only-data] [ro-after-init] [writable data]
  18. * text_size -----^ ^ ^ ^
  19. * ro_size ------------------------| | |
  20. * ro_after_init_size -----------------------------| |
  21. * size -----------------------------------------------------------|
  22. *
  23. * These values are always page-aligned (as is base) when
  24. * CONFIG_STRICT_MODULE_RWX is set.
  25. */
  26. /*
  27. * Since some arches are moving towards PAGE_KERNEL module allocations instead
  28. * of PAGE_KERNEL_EXEC, keep frob_text() and module_enable_x() independent of
  29. * CONFIG_STRICT_MODULE_RWX because they are needed regardless of whether we
  30. * are strict.
  31. */
  32. static void frob_text(const struct module_layout *layout,
  33. int (*set_memory)(unsigned long start, int num_pages))
  34. {
  35. set_memory((unsigned long)layout->base,
  36. PAGE_ALIGN(layout->text_size) >> PAGE_SHIFT);
  37. }
  38. static void frob_rodata(const struct module_layout *layout,
  39. int (*set_memory)(unsigned long start, int num_pages))
  40. {
  41. set_memory((unsigned long)layout->base + layout->text_size,
  42. (layout->ro_size - layout->text_size) >> PAGE_SHIFT);
  43. }
  44. static void frob_ro_after_init(const struct module_layout *layout,
  45. int (*set_memory)(unsigned long start, int num_pages))
  46. {
  47. set_memory((unsigned long)layout->base + layout->ro_size,
  48. (layout->ro_after_init_size - layout->ro_size) >> PAGE_SHIFT);
  49. }
  50. static void frob_writable_data(const struct module_layout *layout,
  51. int (*set_memory)(unsigned long start, int num_pages))
  52. {
  53. set_memory((unsigned long)layout->base + layout->ro_after_init_size,
  54. (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT);
  55. }
  56. static bool layout_check_misalignment(const struct module_layout *layout)
  57. {
  58. return WARN_ON(!PAGE_ALIGNED(layout->base)) ||
  59. WARN_ON(!PAGE_ALIGNED(layout->text_size)) ||
  60. WARN_ON(!PAGE_ALIGNED(layout->ro_size)) ||
  61. WARN_ON(!PAGE_ALIGNED(layout->ro_after_init_size)) ||
  62. WARN_ON(!PAGE_ALIGNED(layout->size));
  63. }
  64. bool module_check_misalignment(const struct module *mod)
  65. {
  66. if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
  67. return false;
  68. return layout_check_misalignment(&mod->core_layout) ||
  69. layout_check_misalignment(&mod->data_layout) ||
  70. layout_check_misalignment(&mod->init_layout);
  71. }
  72. void module_enable_x(const struct module *mod)
  73. {
  74. if (!PAGE_ALIGNED(mod->core_layout.base) ||
  75. !PAGE_ALIGNED(mod->init_layout.base))
  76. return;
  77. frob_text(&mod->core_layout, set_memory_x);
  78. frob_text(&mod->init_layout, set_memory_x);
  79. }
  80. void module_enable_ro(const struct module *mod, bool after_init)
  81. {
  82. if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
  83. return;
  84. #ifdef CONFIG_STRICT_MODULE_RWX
  85. if (!rodata_enabled)
  86. return;
  87. #endif
  88. set_vm_flush_reset_perms(mod->core_layout.base);
  89. set_vm_flush_reset_perms(mod->init_layout.base);
  90. frob_text(&mod->core_layout, set_memory_ro);
  91. frob_rodata(&mod->data_layout, set_memory_ro);
  92. frob_text(&mod->init_layout, set_memory_ro);
  93. frob_rodata(&mod->init_layout, set_memory_ro);
  94. if (after_init)
  95. frob_ro_after_init(&mod->data_layout, set_memory_ro);
  96. }
  97. void module_enable_nx(const struct module *mod)
  98. {
  99. if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
  100. return;
  101. frob_rodata(&mod->data_layout, set_memory_nx);
  102. frob_ro_after_init(&mod->data_layout, set_memory_nx);
  103. frob_writable_data(&mod->data_layout, set_memory_nx);
  104. frob_rodata(&mod->init_layout, set_memory_nx);
  105. frob_writable_data(&mod->init_layout, set_memory_nx);
  106. }
  107. int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
  108. char *secstrings, struct module *mod)
  109. {
  110. const unsigned long shf_wx = SHF_WRITE | SHF_EXECINSTR;
  111. int i;
  112. if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
  113. return 0;
  114. for (i = 0; i < hdr->e_shnum; i++) {
  115. if ((sechdrs[i].sh_flags & shf_wx) == shf_wx) {
  116. pr_err("%s: section %s (index %d) has invalid WRITE|EXEC flags\n",
  117. mod->name, secstrings + sechdrs[i].sh_name, i);
  118. return -ENOEXEC;
  119. }
  120. }
  121. return 0;
  122. }