009-fix-null-dereference-with-lto.patch 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. From 8707194a9f2f0b13e53041b03ebfdbdbd2942e43 Mon Sep 17 00:00:00 2001
  2. From: Mark Wielaard <[email protected]>
  3. Date: Tue, 5 Nov 2024 23:31:14 +0100
  4. Subject: [PATCH 1/1] libelf: Only fetch shdr once in elf_compress[_gnu]
  5. Some compilers assume the second call to elf[32|64]_getshdr can fail
  6. and produce error: potential null pointer dereference. Just store the
  7. result of the first call and reuse (when not NULL).
  8. * libelf/elf_compress.c (elf_compress): Store getshdr result in
  9. a shdr union var.
  10. * libelf/elf_compress_gnu.c (): Likewise
  11. https://sourceware.org/bugzilla/show_bug.cgi?id=32311
  12. Signed-off-by: Mark Wielaard <[email protected]>
  13. ---
  14. libelf/elf_compress.c | 55 +++++++++++++++++++++------------------
  15. libelf/elf_compress_gnu.c | 45 ++++++++++++++------------------
  16. 2 files changed, 48 insertions(+), 52 deletions(-)
  17. --- a/libelf/elf_compress.c
  18. +++ b/libelf/elf_compress.c
  19. @@ -584,25 +584,30 @@ elf_compress (Elf_Scn *scn, int type, un
  20. Elf64_Xword sh_flags;
  21. Elf64_Word sh_type;
  22. Elf64_Xword sh_addralign;
  23. + union shdr
  24. + {
  25. + Elf32_Shdr *s32;
  26. + Elf64_Shdr *s64;
  27. + } shdr;
  28. if (elfclass == ELFCLASS32)
  29. {
  30. - Elf32_Shdr *shdr = elf32_getshdr (scn);
  31. - if (shdr == NULL)
  32. + shdr.s32 = elf32_getshdr (scn);
  33. + if (shdr.s32 == NULL)
  34. return -1;
  35. - sh_flags = shdr->sh_flags;
  36. - sh_type = shdr->sh_type;
  37. - sh_addralign = shdr->sh_addralign;
  38. + sh_flags = shdr.s32->sh_flags;
  39. + sh_type = shdr.s32->sh_type;
  40. + sh_addralign = shdr.s32->sh_addralign;
  41. }
  42. else
  43. {
  44. - Elf64_Shdr *shdr = elf64_getshdr (scn);
  45. - if (shdr == NULL)
  46. + shdr.s64 = elf64_getshdr (scn);
  47. + if (shdr.s64 == NULL)
  48. return -1;
  49. - sh_flags = shdr->sh_flags;
  50. - sh_type = shdr->sh_type;
  51. - sh_addralign = shdr->sh_addralign;
  52. + sh_flags = shdr.s64->sh_flags;
  53. + sh_type = shdr.s64->sh_type;
  54. + sh_addralign = shdr.s64->sh_addralign;
  55. }
  56. if ((sh_flags & SHF_ALLOC) != 0)
  57. @@ -679,17 +684,17 @@ elf_compress (Elf_Scn *scn, int type, un
  58. correctly and ignored when SHF_COMPRESSED is set. */
  59. if (elfclass == ELFCLASS32)
  60. {
  61. - Elf32_Shdr *shdr = elf32_getshdr (scn);
  62. - shdr->sh_size = new_size;
  63. - shdr->sh_addralign = __libelf_type_align (ELFCLASS32, ELF_T_CHDR);
  64. - shdr->sh_flags |= SHF_COMPRESSED;
  65. + shdr.s32->sh_size = new_size;
  66. + shdr.s32->sh_addralign = __libelf_type_align (ELFCLASS32,
  67. + ELF_T_CHDR);
  68. + shdr.s32->sh_flags |= SHF_COMPRESSED;
  69. }
  70. else
  71. {
  72. - Elf64_Shdr *shdr = elf64_getshdr (scn);
  73. - shdr->sh_size = new_size;
  74. - shdr->sh_addralign = __libelf_type_align (ELFCLASS64, ELF_T_CHDR);
  75. - shdr->sh_flags |= SHF_COMPRESSED;
  76. + shdr.s64->sh_size = new_size;
  77. + shdr.s64->sh_addralign = __libelf_type_align (ELFCLASS64,
  78. + ELF_T_CHDR);
  79. + shdr.s64->sh_flags |= SHF_COMPRESSED;
  80. }
  81. __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_CHDR);
  82. @@ -731,17 +736,15 @@ elf_compress (Elf_Scn *scn, int type, un
  83. correctly and ignored when SHF_COMPRESSED is set. */
  84. if (elfclass == ELFCLASS32)
  85. {
  86. - Elf32_Shdr *shdr = elf32_getshdr (scn);
  87. - shdr->sh_size = scn->zdata_size;
  88. - shdr->sh_addralign = scn->zdata_align;
  89. - shdr->sh_flags &= ~SHF_COMPRESSED;
  90. + shdr.s32->sh_size = scn->zdata_size;
  91. + shdr.s32->sh_addralign = scn->zdata_align;
  92. + shdr.s32->sh_flags &= ~SHF_COMPRESSED;
  93. }
  94. else
  95. {
  96. - Elf64_Shdr *shdr = elf64_getshdr (scn);
  97. - shdr->sh_size = scn->zdata_size;
  98. - shdr->sh_addralign = scn->zdata_align;
  99. - shdr->sh_flags &= ~SHF_COMPRESSED;
  100. + shdr.s64->sh_size = scn->zdata_size;
  101. + shdr.s64->sh_addralign = scn->zdata_align;
  102. + shdr.s64->sh_flags &= ~SHF_COMPRESSED;
  103. }
  104. __libelf_reset_rawdata (scn, scn->zdata_base,
  105. --- a/libelf/elf_compress_gnu.c
  106. +++ b/libelf/elf_compress_gnu.c
  107. @@ -59,25 +59,30 @@ elf_compress_gnu (Elf_Scn *scn, int infl
  108. Elf64_Xword sh_flags;
  109. Elf64_Word sh_type;
  110. Elf64_Xword sh_addralign;
  111. + union shdr
  112. + {
  113. + Elf32_Shdr *s32;
  114. + Elf64_Shdr *s64;
  115. + } shdr;
  116. if (elfclass == ELFCLASS32)
  117. {
  118. - Elf32_Shdr *shdr = elf32_getshdr (scn);
  119. - if (shdr == NULL)
  120. + shdr.s32 = elf32_getshdr (scn);
  121. + if (shdr.s32 == NULL)
  122. return -1;
  123. - sh_flags = shdr->sh_flags;
  124. - sh_type = shdr->sh_type;
  125. - sh_addralign = shdr->sh_addralign;
  126. + sh_flags = shdr.s32->sh_flags;
  127. + sh_type = shdr.s32->sh_type;
  128. + sh_addralign = shdr.s32->sh_addralign;
  129. }
  130. else
  131. {
  132. - Elf64_Shdr *shdr = elf64_getshdr (scn);
  133. - if (shdr == NULL)
  134. + shdr.s64 = elf64_getshdr (scn);
  135. + if (shdr.s64 == NULL)
  136. return -1;
  137. - sh_flags = shdr->sh_flags;
  138. - sh_type = shdr->sh_type;
  139. - sh_addralign = shdr->sh_addralign;
  140. + sh_flags = shdr.s64->sh_flags;
  141. + sh_type = shdr.s64->sh_type;
  142. + sh_addralign = shdr.s64->sh_addralign;
  143. }
  144. /* Allocated sections, or sections that are already are compressed
  145. @@ -122,15 +127,9 @@ elf_compress_gnu (Elf_Scn *scn, int infl
  146. sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
  147. Just adjust the sh_size. */
  148. if (elfclass == ELFCLASS32)
  149. - {
  150. - Elf32_Shdr *shdr = elf32_getshdr (scn);
  151. - shdr->sh_size = new_size;
  152. - }
  153. + shdr.s32->sh_size = new_size;
  154. else
  155. - {
  156. - Elf64_Shdr *shdr = elf64_getshdr (scn);
  157. - shdr->sh_size = new_size;
  158. - }
  159. + shdr.s64->sh_size = new_size;
  160. __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_BYTE);
  161. @@ -187,15 +186,9 @@ elf_compress_gnu (Elf_Scn *scn, int infl
  162. sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
  163. Just adjust the sh_size. */
  164. if (elfclass == ELFCLASS32)
  165. - {
  166. - Elf32_Shdr *shdr = elf32_getshdr (scn);
  167. - shdr->sh_size = size;
  168. - }
  169. + shdr.s32->sh_size = size;
  170. else
  171. - {
  172. - Elf64_Shdr *shdr = elf64_getshdr (scn);
  173. - shdr->sh_size = size;
  174. - }
  175. + shdr.s64->sh_size = size;
  176. __libelf_reset_rawdata (scn, buf_out, size, sh_addralign,
  177. __libelf_data_type (&ehdr, sh_type,