Skip to content

Commit

Permalink
livepatch: do not ignore sections with 0 size
Browse files Browse the repository at this point in the history
A side effect of ignoring such sections is that symbols belonging to
them won't be resolved, and that could make relocations belonging to
other sections that reference those symbols fail.

For example it's likely to have an empty .altinstr_replacement with
symbols pointing to it, and marking the section as ignored will
prevent the symbols from being resolved, which in turn will cause any
relocations against them to fail.

In order to solve this do not ignore sections with 0 size, only ignore
sections that don't have the SHF_ALLOC flag set.

Special case such empty sections in move_payload so they are not taken
into account in order to decide whether a livepatch can be safely
re-applied after a revert.

Fixes: 98b728a ('livepatch: Disallow applying after an revert')
Signed-off-by: Roger Pau Monné <[email protected]>
Tested-by: Bjoern Doebel <[email protected]>
Reviewed-by: Ross Lagerwall <[email protected]>
master commit: 0dc1f92
master date: 2022-04-08 10:24:10 +0200
  • Loading branch information
royger authored and jbeulich committed Apr 8, 2022
1 parent 44aae67 commit 46d80ba
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
16 changes: 11 additions & 5 deletions xen/common/livepatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,6 @@ static int move_payload(struct payload *payload, struct livepatch_elf *elf)
* and .shstrtab. For the non-relocate we allocate and copy these
* via other means - and the .rel we can ignore as we only use it
* once during loading.
*
* Also ignore sections with zero size. Those can be for example:
* data, or .bss.
*/
if ( livepatch_elf_ignore_section(elf->sec[i].sec) )
offset[i] = UINT_MAX;
Expand Down Expand Up @@ -362,8 +359,17 @@ static int move_payload(struct payload *payload, struct livepatch_elf *elf)
else if ( elf->sec[i].sec->sh_flags & SHF_WRITE )
{
buf = rw_buf;
rw_buf_sec = i;
rw_buf_cnt++;
if ( elf->sec[i].sec->sh_size )
{
/*
* Special handling of RW empty regions: do not account for
* them in order to decide whether a patch can safely be
* re-applied, but assign them a load address so symbol
* resolution and relocations work.
*/
rw_buf_sec = i;
rw_buf_cnt++;
}
}
else
buf = ro_buf;
Expand Down
2 changes: 1 addition & 1 deletion xen/include/xen/livepatch_elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ int livepatch_elf_perform_relocs(struct livepatch_elf *elf);

static inline bool livepatch_elf_ignore_section(const Elf_Shdr *sec)
{
return !(sec->sh_flags & SHF_ALLOC) || sec->sh_size == 0;
return !(sec->sh_flags & SHF_ALLOC);
}
#endif /* __XEN_LIVEPATCH_ELF_H__ */

Expand Down

0 comments on commit 46d80ba

Please sign in to comment.