From: Joe Lawrence <joe.lawrence@redhat.com>
To: Lukas Hruska <lhruska@suse.cz>
Cc: pmladek@suse.com, mbenes@suse.cz, jpoimboe@kernel.org,
live-patching@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kbuild@vger.kernel.org, mpdesouza@suse.com,
Josh Poimboeuf <jpoimboe@redhat.com>
Subject: Re: [PATCH v2 2/6] livepatch: Add klp-convert tool
Date: Wed, 29 May 2024 17:04:16 -0400 [thread overview]
Message-ID: <ZleYUN4z4jizCteM@redhat.com> (raw)
In-Reply-To: <20240516133009.20224-3-lhruska@suse.cz>
Hi Lukas,
As mentioned offlist, reviewing and testing this is on my TODO list, but
here are some early notes ...
On Thu, May 16, 2024 at 03:30:05PM +0200, Lukas Hruska wrote:
> Livepatches need to access external symbols which can't be handled
> by the normal relocation mechanism. It is needed for two types
> of symbols:
>
> + Symbols which can be local for the original livepatched function.
> The alternative implementation in the livepatch sees them
> as external symbols.
>
> + Symbols in modules which are exported via EXPORT_SYMBOL*(). They
> must be handled special way otherwise the livepatch module would
> depend on the livepatched one. Loading such livepatch would cause
> loading the other module as well.
>
> The address of these symbols can be found via kallsyms. Or they can
> be relocated using livepatch specific relocation sections as specified
> in Documentation/livepatch/module-elf-format.txt.
>
> Currently, there is no trivial way to embed the required information as
> requested in the final livepatch elf object. klp-convert solves this
> problem by using annotations in the elf object to convert the relocation
> accordingly to the specification, enabling it to be handled by the
> livepatch loader.
>
> Given the above, create scripts/livepatch to hold tools developed for
> livepatches and add source files for klp-convert there.
>
> Allow to annotate such external symbols in the livepatch by a macro
> KLP_RELOC_SYMBOL(). It will create symbol with all needed
> metadata. For example:
>
> extern char *saved_command_line \
> KLP_RELOC_SYMBOL(vmlinux, vmlinux, saved_command_line, 0);
Nit: should this be KLP_RELOC_SYMBOL_POS if it including the 0 position?
(Or KLP_RELOC_SYMBOL and omit the implied 0-th position.)
> diff --git a/scripts/livepatch/elf.c b/scripts/livepatch/elf.c
> --- /dev/null
> +++ b/scripts/livepatch/elf.c
> +static int update_shstrtab(struct elf *elf)
> +{
> + struct section *shstrtab, *sec;
> + size_t orig_size, new_size = 0, offset, len;
> + char *buf;
> +
> + shstrtab = find_section_by_name(elf, ".shstrtab");
> + if (!shstrtab) {
> + WARN("can't find .shstrtab");
> + return -1;
> + }
> +
> + orig_size = new_size = shstrtab->size;
> +
> + list_for_each_entry(sec, &elf->sections, list) {
> + if (sec->sh.sh_name != ~0U)
> + continue;
> + new_size += strlen(sec->name) + 1;
> + }
> +
> + if (new_size == orig_size)
> + return 0;
> +
> + buf = malloc(new_size);
> + if (!buf) {
> + WARN("malloc failed");
> + return -1;
> + }
> + memcpy(buf, (void *)shstrtab->data, orig_size);
While reviewing klp-convert v7 [1], Alexey Dobriyan notes here,
"This code is called realloc(). :-)"
[1] https://lore.kernel.org/live-patching/4ce29654-4e1e-4680-9c25-715823ff5e02@p183/
> +static int update_strtab(struct elf *elf)
> +{
> + struct section *strtab;
> + struct symbol *sym;
> + size_t orig_size, new_size = 0, offset, len;
> + char *buf;
> +
> + strtab = find_section_by_name(elf, ".strtab");
> + if (!strtab) {
> + WARN("can't find .strtab");
> + return -1;
> + }
> +
> + orig_size = new_size = strtab->size;
> +
> + list_for_each_entry(sym, &elf->symbols, list) {
> + if (sym->sym.st_name != ~0U)
> + continue;
> + new_size += strlen(sym->name) + 1;
> + }
> +
> + if (new_size == orig_size)
> + return 0;
> +
> + buf = malloc(new_size);
> + if (!buf) {
> + WARN("malloc failed");
> + return -1;
> + }
> + memcpy(buf, (void *)strtab->data, orig_size);
I think Alexey's realloc suggestion would apply here, too.
> +static int write_file(struct elf *elf, const char *file)
> +{
> + int fd;
> + Elf *e;
> + GElf_Ehdr eh, ehout;
> + Elf_Scn *scn;
> + Elf_Data *data;
> + GElf_Shdr sh;
> + struct section *sec;
> +
> + fd = creat(file, 0664);
> + if (fd == -1) {
> + WARN("couldn't create %s", file);
> + return -1;
> + }
> +
> + e = elf_begin(fd, ELF_C_WRITE, NULL);
Alexy also found an ELF coding bug:
"elf_end() doesn't close descriptor, so there is potentially corrupted
data. There is no unlink() call if writes fail as well."
> +void elf_close(struct elf *elf)
> +{
> + struct section *sec, *tmpsec;
> + struct symbol *sym, *tmpsym;
> + struct rela *rela, *tmprela;
> +
> + list_for_each_entry_safe(sym, tmpsym, &elf->symbols, list) {
> + list_del(&sym->list);
> + free(sym);
> + }
> + list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) {
> + list_for_each_entry_safe(rela, tmprela, &sec->relas, list) {
> + list_del(&rela->list);
> + free(rela);
> + }
> + list_del(&sec->list);
> + free(sec);
> + }
> + if (elf->fd > 0)
> + close(elf->fd);
Alexy found another ELF coding bug here:
"Techically, it is "fd >= 0"."
I had coded fixes for these in a v8-devel that I never finished. It
shouldn't be too hard to fix these up in the minimal version of the
patchset, but lmk if you'd like a patch.
That's all for now. My plan is to try and turn off kpatch-build's
klp-relocation code and see how passing through to klp-convert fares.
That would give us a good comparison of real-world examples that need to
be handled and tested.
--
Joe
next prev parent reply other threads:[~2024-05-29 21:04 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-16 13:30 [PATCH v2 0/5] livepatch: klp-convert tool - Minimal version Lukas Hruska
2024-05-16 13:30 ` [PATCH v2 1/6] livepatch: Create and include UAPI headers Lukas Hruska
2024-05-16 13:30 ` [PATCH v2 2/6] livepatch: Add klp-convert tool Lukas Hruska
2024-05-22 10:05 ` Petr Mladek
2024-05-29 21:04 ` Joe Lawrence [this message]
2024-05-30 20:07 ` Joe Lawrence
2024-06-06 10:05 ` Lukas Hruska
2024-05-16 13:30 ` [PATCH v2 3/6] kbuild/modpost: integrate klp-convert Lukas Hruska
2024-05-16 13:30 ` [PATCH v2 4/6] livepatch: Add sample livepatch module Lukas Hruska
2024-05-22 11:37 ` Petr Mladek
2024-05-16 13:30 ` [PATCH v2 5/6] documentation: Update on livepatch elf format Lukas Hruska
2024-05-16 13:30 ` [PATCH v2 6/6] selftests: livepatch: Test livepatching function using an external symbol Lukas Hruska
2024-05-22 11:44 ` Petr Mladek
2024-05-29 14:05 ` [PATCH v2 0/5] livepatch: klp-convert tool - Minimal version Marcos Paulo de Souza
-- strict thread matches above, loose matches on Subject: below --
2024-05-18 18:29 [PATCH v2 6/6] selftests: livepatch: Test livepatching function using an external symbol kernel test robot
2024-05-23 7:21 ` kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZleYUN4z4jizCteM@redhat.com \
--to=joe.lawrence@redhat.com \
--cc=jpoimboe@kernel.org \
--cc=jpoimboe@redhat.com \
--cc=lhruska@suse.cz \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=mpdesouza@suse.com \
--cc=pmladek@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.