diff options
| author | Mark Wielaard <[email protected]> | 2024-11-05 23:31:14 +0100 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2024-11-07 16:29:59 +0100 |
| commit | 8707194a9f2f0b13e53041b03ebfdbdbd2942e43 (patch) | |
| tree | bb9b0319e418d7e6fd6e5a5409aca91b85a25ff9 /libelf | |
| parent | e425a70469436c704e6c24dd4bc2abb8fb24b61d (diff) | |
libelf: Only fetch shdr once in elf_compress[_gnu]
Some compilers assume the second call to elf[32|64]_getshdr can fail
and produce error: potential null pointer dereference. Just store the
result of the first call and reuse (when not NULL).
* libelf/elf_compress.c (elf_compress): Store getshdr result in
a shdr union var.
* libelf/elf_compress_gnu.c (): Likewise
https://sourceware.org/bugzilla/show_bug.cgi?id=32311
Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libelf')
| -rw-r--r-- | libelf/elf_compress.c | 55 | ||||
| -rw-r--r-- | libelf/elf_compress_gnu.c | 45 |
2 files changed, 48 insertions, 52 deletions
diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c index 2cd32a6f..a2fa1f08 100644 --- a/libelf/elf_compress.c +++ b/libelf/elf_compress.c @@ -584,25 +584,30 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags) Elf64_Xword sh_flags; Elf64_Word sh_type; Elf64_Xword sh_addralign; + union shdr + { + Elf32_Shdr *s32; + Elf64_Shdr *s64; + } shdr; if (elfclass == ELFCLASS32) { - Elf32_Shdr *shdr = elf32_getshdr (scn); - if (shdr == NULL) + shdr.s32 = elf32_getshdr (scn); + if (shdr.s32 == NULL) return -1; - sh_flags = shdr->sh_flags; - sh_type = shdr->sh_type; - sh_addralign = shdr->sh_addralign; + sh_flags = shdr.s32->sh_flags; + sh_type = shdr.s32->sh_type; + sh_addralign = shdr.s32->sh_addralign; } else { - Elf64_Shdr *shdr = elf64_getshdr (scn); - if (shdr == NULL) + shdr.s64 = elf64_getshdr (scn); + if (shdr.s64 == NULL) return -1; - sh_flags = shdr->sh_flags; - sh_type = shdr->sh_type; - sh_addralign = shdr->sh_addralign; + sh_flags = shdr.s64->sh_flags; + sh_type = shdr.s64->sh_type; + sh_addralign = shdr.s64->sh_addralign; } if ((sh_flags & SHF_ALLOC) != 0) @@ -679,17 +684,17 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags) correctly and ignored when SHF_COMPRESSED is set. */ if (elfclass == ELFCLASS32) { - Elf32_Shdr *shdr = elf32_getshdr (scn); - shdr->sh_size = new_size; - shdr->sh_addralign = __libelf_type_align (ELFCLASS32, ELF_T_CHDR); - shdr->sh_flags |= SHF_COMPRESSED; + shdr.s32->sh_size = new_size; + shdr.s32->sh_addralign = __libelf_type_align (ELFCLASS32, + ELF_T_CHDR); + shdr.s32->sh_flags |= SHF_COMPRESSED; } else { - Elf64_Shdr *shdr = elf64_getshdr (scn); - shdr->sh_size = new_size; - shdr->sh_addralign = __libelf_type_align (ELFCLASS64, ELF_T_CHDR); - shdr->sh_flags |= SHF_COMPRESSED; + shdr.s64->sh_size = new_size; + shdr.s64->sh_addralign = __libelf_type_align (ELFCLASS64, + ELF_T_CHDR); + shdr.s64->sh_flags |= SHF_COMPRESSED; } __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_CHDR); @@ -731,17 +736,15 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags) correctly and ignored when SHF_COMPRESSED is set. */ if (elfclass == ELFCLASS32) { - Elf32_Shdr *shdr = elf32_getshdr (scn); - shdr->sh_size = scn->zdata_size; - shdr->sh_addralign = scn->zdata_align; - shdr->sh_flags &= ~SHF_COMPRESSED; + shdr.s32->sh_size = scn->zdata_size; + shdr.s32->sh_addralign = scn->zdata_align; + shdr.s32->sh_flags &= ~SHF_COMPRESSED; } else { - Elf64_Shdr *shdr = elf64_getshdr (scn); - shdr->sh_size = scn->zdata_size; - shdr->sh_addralign = scn->zdata_align; - shdr->sh_flags &= ~SHF_COMPRESSED; + shdr.s64->sh_size = scn->zdata_size; + shdr.s64->sh_addralign = scn->zdata_align; + shdr.s64->sh_flags &= ~SHF_COMPRESSED; } __libelf_reset_rawdata (scn, scn->zdata_base, diff --git a/libelf/elf_compress_gnu.c b/libelf/elf_compress_gnu.c index 8e20b30e..006e2ae4 100644 --- a/libelf/elf_compress_gnu.c +++ b/libelf/elf_compress_gnu.c @@ -59,25 +59,30 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags) Elf64_Xword sh_flags; Elf64_Word sh_type; Elf64_Xword sh_addralign; + union shdr + { + Elf32_Shdr *s32; + Elf64_Shdr *s64; + } shdr; if (elfclass == ELFCLASS32) { - Elf32_Shdr *shdr = elf32_getshdr (scn); - if (shdr == NULL) + shdr.s32 = elf32_getshdr (scn); + if (shdr.s32 == NULL) return -1; - sh_flags = shdr->sh_flags; - sh_type = shdr->sh_type; - sh_addralign = shdr->sh_addralign; + sh_flags = shdr.s32->sh_flags; + sh_type = shdr.s32->sh_type; + sh_addralign = shdr.s32->sh_addralign; } else { - Elf64_Shdr *shdr = elf64_getshdr (scn); - if (shdr == NULL) + shdr.s64 = elf64_getshdr (scn); + if (shdr.s64 == NULL) return -1; - sh_flags = shdr->sh_flags; - sh_type = shdr->sh_type; - sh_addralign = shdr->sh_addralign; + sh_flags = shdr.s64->sh_flags; + sh_type = shdr.s64->sh_type; + sh_addralign = shdr.s64->sh_addralign; } /* Allocated sections, or sections that are already are compressed @@ -122,15 +127,9 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags) sh_flags won't have a SHF_COMPRESSED hint in the GNU format. Just adjust the sh_size. */ if (elfclass == ELFCLASS32) - { - Elf32_Shdr *shdr = elf32_getshdr (scn); - shdr->sh_size = new_size; - } + shdr.s32->sh_size = new_size; else - { - Elf64_Shdr *shdr = elf64_getshdr (scn); - shdr->sh_size = new_size; - } + shdr.s64->sh_size = new_size; __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_BYTE); @@ -187,15 +186,9 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags) sh_flags won't have a SHF_COMPRESSED hint in the GNU format. Just adjust the sh_size. */ if (elfclass == ELFCLASS32) - { - Elf32_Shdr *shdr = elf32_getshdr (scn); - shdr->sh_size = size; - } + shdr.s32->sh_size = size; else - { - Elf64_Shdr *shdr = elf64_getshdr (scn); - shdr->sh_size = size; - } + shdr.s64->sh_size = size; __libelf_reset_rawdata (scn, buf_out, size, sh_addralign, __libelf_data_type (&ehdr, sh_type, |
