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.

73 lines
4.1 KiB

  1. 1. Design
  2. The goal of NOEXEC is to prevent the injection and execution of code into a
  3. task's address space and render this exploit technique unusable under PaX.
  4. There are two ways of introducing new executable code into a task's address
  5. space: creating an executable mapping or modifying an already existing
  6. writable/executable mapping. The first method is not handled by PaX, we
  7. believe that various access control systems should manage it. The second
  8. method can be stopped if we prevent the creation of writable/executable
  9. mappings altogether. This also implies that we can have proper executable
  10. semantics for mappings (i.e., one that is not coupled to the readability
  11. of the mapping).
  12. While having the executable semantics is not a security feature itself, it
  13. plays an important role in the PaX strategy because it allows the separation
  14. of the writable and executable properties on memory pages (in most systems
  15. if a page is writable it is also readable and hence executable). This in
  16. turn makes a number of approaches possible that otherwise would be easy to
  17. defeat.
  18. From another point of view NOEXEC is a form of least privilege enforcement.
  19. In our case the idea is that if some data in a task's address space does
  20. not need to be executable then it should not be, hence we need the ability
  21. to mark such data (pages) non-executable. Taking this idea further, if an
  22. application does not need to generate code at runtime then it should not
  23. be able to, therefore we need the ability to prevent state transitions on
  24. memory pages between writability and executability (if an application does
  25. need the ability to generate code at runtime, then these restrictions cannot
  26. be applied to it nor can we then make guarantees about exploit techniques
  27. that are unusable against its bugs).
  28. The first feature NOEXEC implements is the executable semantics on memory
  29. pages. On architectures where the Memory Management Unit (MMU) has direct
  30. support for this we can trivially make use of it. The main and (so far)
  31. only exception is IA-32 where we have to resort to some tricks to get true
  32. non-executable pages. The two approaches PaX has are based on the paging
  33. and the segmentation logic of IA-32 and make various tradeoffs between
  34. performance and usability (the other architectures make no such tradeoff).
  35. The second feature of NOEXEC is making the kernel actually use the finally
  36. available executable semantics. In particular, PaX makes the stack and the
  37. heap (all anonymous mappings in general) non-executable. Furthermore, ELF
  38. file mappings are created with the requested access rigths, that is, only
  39. ELF segments holding code will actually be executable.
  40. The last feature of NOEXEC is the locking down of permissions on memory
  41. pages. This means that we prevent the creation of writable/executable file
  42. mappings (anonymous mappings are already made non-executable) and we also
  43. refuse to turn a writable or non-executable mapping into an executable one
  44. and vice versa. Since this lockdown breaks real life applications that do
  45. need to generate code at runtime, PaX allows to relax these restrictions
  46. on a per executable basis (along with other features).
  47. 2. Implementation
  48. The Linux implementation of NOEXEC is split into two main feature sets: the
  49. actual non-executable page implementations (PAGEEXEC and SEGMEXEC, the latter
  50. is IA-32 only) and the page protection restrictions (MPROTECT).
  51. PAGEEXEC uses the paging logic of the CPU whereas SEGMEXEC uses the IA-32
  52. specific segmentation logic to implement the non-executable page semantics
  53. (the exact details are discussed in separate documents). There is also a set
  54. of changes that actually makes the kernel use the non-executable page feature
  55. where it makes sense, e.g., the stack or the brk() managed heap - this is
  56. implemented by simply modifying the appropriate constants to not request
  57. executable memory for these areas.
  58. Since page protection rights originate from mmap() and can be changed by
  59. mprotect(), they are modified to enforce the restrictions, the details are
  60. described in the MPROTECT document.