Commit 72cc02d1 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

compel: fix sign-extension in get_strings_section

Well, I hope, I will not make integer promotion mistakes anymore:
> 6.3.1.1
>   If an int can represent all values of the original type, the value
> is converted to an int; otherwise, it is converted to an unsigned int.
> These are called the integer promotions.48) All other types are
> unchanged by the integer promotions.

>>> CID 161317:    (SIGN_EXTENSION)
>>> Suspicious implicit sign extension: "hdr->e_shentsize" with type
    "unsigned short" (16 bits, unsigned) is promoted in
    "hdr->e_shentsize * hdr->e_shnum" to type "int" (32 bits, signed),
    then sign-extended to type "unsigned long" (64 bits, unsigned).
    If "hdr->e_shentsize * hdr->e_shnum" is greater than 0x7FFFFFFF,
    the upper bits of the result will all be 1.
96      size_t sec_table_size = hdr->e_shentsize * hdr->e_shnum;

>>> CID 161317:    (SIGN_EXTENSION)
>>> Suspicious implicit sign extension: "hdr->e_shentsize" with type
    "unsigned short" (16 bits, unsigned) is promoted in
    "hdr->e_shentsize * hdr->e_shstrndx" to type "int" (32 bits, signed),
    then sign-extended to type "unsigned long" (64 bits, unsigned).
    If "hdr->e_shentsize * hdr->e_shstrndx" is greater than 0x7FFFFFFF,
    the upper bits of the result will all be 1.
111             addr = sec_table + hdr->e_shentsize * hdr->e_shstrndx;

Fixes: #157
Fixes: commit 36664a3cabec ("compel: separate get_strings_section from
__handle_elf").

Reported-by: Coverity
Reported-by: 's avatarAndrew Vagin <avagin@virtuozzo.com>
Cc: Andrew Vagin <avagin@virtuozzo.com>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Acked-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 6fe6a283
...@@ -93,7 +93,7 @@ static bool is_header_supported(Ehdr_t *hdr) ...@@ -93,7 +93,7 @@ static bool is_header_supported(Ehdr_t *hdr)
static const char *get_strings_section(Ehdr_t *hdr, uintptr_t mem, size_t size) static const char *get_strings_section(Ehdr_t *hdr, uintptr_t mem, size_t size)
{ {
size_t sec_table_size = hdr->e_shentsize * hdr->e_shnum; size_t sec_table_size = ((size_t) hdr->e_shentsize) * hdr->e_shnum;
uintptr_t sec_table = mem + hdr->e_shoff; uintptr_t sec_table = mem + hdr->e_shoff;
Shdr_t *secstrings_hdr; Shdr_t *secstrings_hdr;
uintptr_t addr; uintptr_t addr;
...@@ -108,7 +108,7 @@ static const char *get_strings_section(Ehdr_t *hdr, uintptr_t mem, size_t size) ...@@ -108,7 +108,7 @@ static const char *get_strings_section(Ehdr_t *hdr, uintptr_t mem, size_t size)
* strings section header's offset in section headers table is * strings section header's offset in section headers table is
* (size of section header * index of string section header) * (size of section header * index of string section header)
*/ */
addr = sec_table + hdr->e_shentsize * hdr->e_shstrndx; addr = sec_table + ((size_t) hdr->e_shentsize) * hdr->e_shstrndx;
if (__ptr_struct_oob(addr, sizeof(Shdr_t), if (__ptr_struct_oob(addr, sizeof(Shdr_t),
sec_table, sec_table + sec_table_size)) { sec_table, sec_table + sec_table_size)) {
pr_err("String section header @%#zx is out of [%#zx, %#zx)\n", pr_err("String section header @%#zx is out of [%#zx, %#zx)\n",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment