This patchset removes livepatch's need for architecture-specific relocation
code by leveraging existing code in the module loader to perform
arch-dependent work. Specifically, instead of duplicating code and
re-implementing what the apply_relocate_add() function in the module loader
already does in livepatch's klp_write_module_reloc(), we reuse
apply_relocate_add() to write relocations. The hope is that this will make
livepatch more easily portable to other architectures and greatly reduce
the amount of arch-specific code required to port livepatch to a particular
architecture.
Background: Why does livepatch need to write its own relocations?
==
A typical livepatch module contains patched versions of functions that can
reference non-exported global symbols and non-included local symbols.
Relocations referencing these types of symbols cannot be left in as-is
since the kernel module loader cannot resolve them and will therefore
reject the livepatch module. Furthermore, we cannot apply relocations that
affect modules not loaded yet at run time (e.g. a patch to a driver). The
current kpatch build system therefore solves this problem by embedding
special "dynrela" (dynamic reloc) sections in the resulting patch module
Elf output. Using these dynrela sections, livepatch can correctly resolve
symbols while taking into account its scope and what module the symbol
belongs to, and then manually apply the dynamic relocations.
Motivation: Why is having arch-dependent relocation code a problem?
==
The original motivation for this patchset stems from the increasing
roadblocks encountered while attempting to port livepatch to s390.
Specifically, there were problems dealing with s390 PLT and GOT relocation
types (R_390_{PLT,GOT}), which are handled differently from x86's
relocation types (which are much simpler to deal with, and a single
livepatch function (klp_write_module_reloc()) has been sufficient enough).
These s390 reloc types cannot be handled by simply performing a calculation
(as in the x86 case). For s390 modules with PLT/GOT relocations, the kernel
module loader allocates and fills in PLT+GOT table entries for every symbol
referenced by a PLT/GOT reloc in module core memory. So the problem of
porting livepatch to s390 became much more complicated than simply writing
an s390-specific klp_write_module_reloc() function. How can livepatch
handle these relocation types if the s390 module loader needs to allocate
and fill PLT/GOT entries ahead of time? The potential solutions were: 1)
have livepatch possibly allocate and maintain its own PLT/GOT tables for
every patch module (requiring even more arch-specific code), 2) modify the
s390 module loader heavily to accommodate livepatch modules (i.e. allocate
all the needed PLT/GOT entries for livepatch in advance but refrain from
applying relocations for to-be-patched modules), or 3) eliminate this
potential mess by leveraging module loader code to do all the relocation
work, letting livepatch off the hook completely. Solution #3 is what this
patchset implements.
How does this patchset remedy these problems?
==
Reusing the module loader code to perform livepatch relocations means that
livepatch no longer needs arch-specific reloc code and the aforementioned
problems with s390 PLT/GOT reloc types disappear (because we let the module
loader do all the relocation work for us). It will enable livepatch to be
more easily ported to other architectures.
Summary of proposed changes
==
This patch series enables livepatch to use the module loader's
apply_relocate_add() function to apply livepatch relocations (i.e. what
used to be dynrelas). apply_relocate_add() requires access to a patch
module's section headers, symbol table, reloc section indices, etc., and all
of these are accessible through the load_info struct used in the module
loader. Therefore we persist module Elf information (copied from load_info)
for livepatch modules.
The ELF-related changes enable livepatch to patch modules that are not yet
loaded (as well as patch vmlinux when kaslr is enabled). In order to use
apply_relocate_add(), we need real SHT_RELA sections to pass in. A
complication here is that relocations for not-yet-loaded modules should not
be applied when the patch module loads; they should only be applied once
the target module is loaded. Thus kpatch build scripts were modified to
output a livepatch module that contains special .klp.rela. sections that
are managed by livepatch and are applied at the appropriate time (i.e. when
target module loads). They are marked with a special SHF_RELA_LIVEPATCH
section flag to indicate to the module loader that livepatch will handle
them. The SHN_LIVEPATCH shndx marks symbols that need to be resolved
once their respective target module loads. So, the module loader ignores
these symbols and does not attempt to resolve them. These ELF constants
were selected from OS-specific ranges according to the definitions from
glibc.
Patches based on linux-next.
Previous patchset (v4) found here:
http://lkml.kernel.org/g/1454548271-24923-1-git-send-email-jeyu@redhat.com
v5:
- The '%[' format specifier for sscanf() is now available on linux-next,
so use sscanf() to parse symbol and section names instead of using
multiple clumsy klp_get_* helper functions and strspn/strcspn calls.
- Removed some unnecessary comments
- For symtab access, just use the core symtab mod->core_kallsyms.symtab
(what used to be mod->core_symtab). If we use mod->kallsyms.symtab
(what used to be mod->symtab), during the patch module init process we
would be using the init symbol table (the one in module init memory)
instead of the core symbol table, because mod->kallsyms only gets reassigned
to mod->core_kallsyms *after* do_one_initcall(). Though in the case of
livepatch modules both the symbol tables in init vs core memory are
identical, I think it is better to be consistent.
v4:
- Way more error checking for all the string manipulation on
livepatch symbol names and sections.
- Handle error conditions such as loading a klp module on a
!CONFIG_LIVEPATCH kernel
- Don't encode sympos in a symbol's st_other field. Instead, append it
to the symbol name in the form .klp.sym.objname.symname,sympos
- Instead of a half initialized copy of the load_info struct in
mod->info, define a livepatch specific struct (klp_modinfo) instead
that contains just the needed Elf info.
- Much more detailed documentation about patch module requirements
and the module elf format.
v3:
- Remove usage of the klp_reloc_sec struct, since we can simply loop
through the patch module's section headers.
- Remove necessity of the "external" flag by prefixing symbol names
with the object name and extracting this name during symbol
resolution.
- Create CONFIG_LIVEPATCH and !CONFIG_LIVEPATCH versions of
{copy,free}_module_elf(), is_livepatch_module(), and
check_livepatch_modinfo().
- Encoded symbol position of a livepatch sym in its st_other field.
- Various bug fixes from v2
v2:
- Copy only the minimum required Elf information for livepatch modules to
make the call to apply_relocate_add(), not the entire load_info struct
and the redundant copy of the module in memory
- Add module->klp flag for simple identification of livepatch modules
- s390: remove redundant vfree() and preserve mod_arch_specific if
livepatch module
- Use array format instead of a linked list for klp_reloc_secs
- Add new documentation describing the format of a livepatch module in
Documentation/livepatch
Jessica Yu (6):
Elf: add livepatch-specific Elf constants
module: preserve Elf information for livepatch modules
module: s390: keep mod_arch_specific for livepatch modules
livepatch: reuse module loader code to write relocations
samples: livepatch: mark as livepatch module
Documentation: livepatch: outline Elf format and requirements for
patch modules
Documentation/livepatch/module-elf-format.txt | 311 ++++++++++++++++++++++++++
arch/s390/include/asm/livepatch.h | 7 -
arch/s390/kernel/module.c | 6 +-
arch/x86/include/asm/livepatch.h | 2 -
arch/x86/kernel/Makefile | 1 -
arch/x86/kernel/livepatch.c | 70 ------
include/linux/livepatch.h | 20 --
include/linux/module.h | 25 +++
include/uapi/linux/elf.h | 10 +-
kernel/livepatch/core.c | 140 +++++++-----
kernel/module.c | 123 +++++++++-
samples/livepatch/livepatch-sample.c | 1 +
12 files changed, 552 insertions(+), 164 deletions(-)
create mode 100644 Documentation/livepatch/module-elf-format.txt
delete mode 100644 arch/x86/kernel/livepatch.c
--
2.4.3
Livepatch manages its own relocation sections and symbols in order to be
able to reuse module loader code to write relocations. This removes
livepatch's dependence on separate "dynrela" sections to write relocations
and also allows livepatch to patch modules that are not yet loaded.
The livepatch Elf relocation section flag (SHF_RELA_LIVEPATCH),
and symbol section index (SHN_LIVEPATCH) allow both livepatch and the
module loader to identity livepatch relocation sections and livepatch
symbols.
Livepatch relocation sections are marked with SHF_RELA_LIVEPATCH to
indicate to the module loader that it should not apply that relocation
section and that livepatch will handle them.
The SHN_LIVEPATCH shndx marks symbols that will be resolved by livepatch.
The module loader ignores these symbols and does not attempt to resolve
them.
The values of these Elf constants were selected from OS-specific
ranges according to the definitions from glibc.
Signed-off-by: Jessica Yu <redacted>
---
include/uapi/linux/elf.h | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
For livepatch modules, copy Elf section, symbol, and string information
from the load_info struct in the module loader. Persist copies of the
original symbol table and string table.
Livepatch manages its own relocation sections in order to reuse module
loader code to write relocations. Livepatch modules must preserve Elf
information such as section indices in order to apply livepatch relocation
sections using the module loader's apply_relocate_add() function.
In order to apply livepatch relocation sections, livepatch modules must
keep a complete copy of their original symbol table in memory. Normally, a
stripped down copy of a module's symbol table (containing only "core"
symbols) is made available through module->core_symtab. But for livepatch
modules, the symbol table copied into memory on module load must be exactly
the same as the symbol table produced when the patch module was compiled.
This is because the relocations in each livepatch relocation section refer
to their respective symbols with their symbol indices, and the original
symbol indices (and thus the symtab ordering) must be preserved in order
for apply_relocate_add() to find the right symbol.
Signed-off-by: Jessica Yu <redacted>
---
include/linux/module.h | 25 ++++++++++
kernel/module.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 146 insertions(+), 2 deletions(-)
@@ -456,7 +465,11 @@ struct module {#endif#ifdef CONFIG_LIVEPATCH+boolklp;/* Is this a livepatch module? */boolklp_alive;++/* Elf information */+structklp_modinfo*klp_info;#endif#ifdef CONFIG_MODULE_UNLOAD
@@ -630,6 +643,18 @@ static inline bool module_requested_async_probing(struct module *module)returnmodule&&module->async_probe_requested;}+#ifdef CONFIG_LIVEPATCH+staticinlineboolis_livepatch_module(structmodule*mod)+{+returnmod->klp;+}+#else /* !CONFIG_LIVEPATCH */+staticinlineboolis_livepatch_module(structmodule*mod)+{+returnfalse;+}+#endif /* CONFIG_LIVEPATCH */+#else /* !CONFIG_MODULES... *//* Given an address, look for it in the exception tables. */
@@ -2009,6 +2085,9 @@ static void free_module(struct module *mod)/* Free any allocated parameters. */destroy_params(mod->kp,mod->num_kp);+if(is_livepatch_module(mod))+free_module_elf(mod);+/* Now we can delete it from the lists */mutex_lock(&module_mutex);/* Unlink carefully: kallsyms could be walking list. */
@@ -2124,6 +2203,10 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)(long)sym[i].st_value);break;+caseSHN_LIVEPATCH:+/* Livepatch symbols are resolved by livepatch */+break;+caseSHN_UNDEF:ksym=resolve_symbol_wait(mod,info,name);/* Ok if resolved. */
@@ -2172,6 +2255,10 @@ static int apply_relocations(struct module *mod, const struct load_info *info)if(!(info->sechdrs[infosec].sh_flags&SHF_ALLOC))continue;+/* Livepatch relocation sections are applied by livepatch */+if(info->sechdrs[i].sh_flags&SHF_RELA_LIVEPATCH)+continue;+if(info->sechdrs[i].sh_type==SHT_REL)err=apply_relocate(info->sechdrs,info->strtab,info->index.sym,i,mod);
@@ -2467,7 +2554,7 @@ static void layout_symtab(struct module *mod, struct load_info *info)/* Compute total space required for the core symbols' strtab. */for(ndst=i=0;i<nsrc;i++){-if(i==0||+if(i==0||is_livepatch_module(mod)||is_core_symbol(src+i,info->sechdrs,info->hdr->e_shnum,info->index.pcpu)){strtab_size+=strlen(&info->strtab[src[i].st_name])+1;
@@ -2665,6 +2752,26 @@ static int copy_chunked_from_user(void *dst, const void __user *usrc, unsigned lreturn0;}+#ifdef CONFIG_LIVEPATCH+staticintfind_livepatch_modinfo(structmodule*mod,structload_info*info)+{+mod->klp=get_modinfo(info,"livepatch")?true:false;++return0;+}+#else /* !CONFIG_LIVEPATCH */+staticintfind_livepatch_modinfo(structmodule*mod,structload_info*info)+{+if(get_modinfo(info,"livepatch")){+pr_err("%s: module is marked as livepatch module, but livepatch support is disabled"+mod->name);+return-ENOEXEC;+}++return0;+}+#endif /* CONFIG_LIVEPATCH */+/* Sets info->hdr and info->len. */staticintcopy_module_from_user(constvoid__user*umod,unsignedlonglen,structload_info*info)
@@ -2819,6 +2926,10 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)"is unknown, you have been warned.\n",mod->name);}+err=find_livepatch_modinfo(mod,info);+if(err)+returnerr;+/* Set up license info based on the info section */set_license(mod,get_modinfo(info,"license"));
@@ -3476,6 +3587,12 @@ static int load_module(struct load_info *info, const char __user *uargs,if(err<0)gotobug_cleanup;+if(is_livepatch_module(mod)){+err=copy_module_elf(mod,info);+if(err<0)+gotosysfs_cleanup;+}+/* Get rid of temporary copy. */free_copy(info);
Livepatch needs to utilize the symbol information contained in the
mod_arch_specific struct in order to be able to call the s390
apply_relocate_add() function to apply relocations. Keep a reference to
syminfo if the module is a livepatch module. Remove the redundant vfree()
in module_finalize() since module_arch_freeing_init() (which also frees
those structures) is called in do_init_module(). If the module isn't a
livepatch module, we free the structures in module_arch_freeing_init() as
usual.
Signed-off-by: Jessica Yu <redacted>
---
arch/s390/kernel/module.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
Reuse module loader code to write relocations, thereby eliminating the need
for architecture specific relocation code in livepatch. Specifically, reuse
the apply_relocate_add() function in the module loader to write relocations
instead of duplicating functionality in livepatch's arch-dependent
klp_write_module_reloc() function.
In order to accomplish this, livepatch modules manage their own relocation
sections (marked with the SHF_RELA_LIVEPATCH section flag) and
livepatch-specific symbols (marked with SHN_LIVEPATCH symbol section
index). To apply livepatch relocation sections, livepatch symbols
referenced by relocs are resolved and then apply_relocate_add() is called
to apply those relocations.
In addition, remove x86 livepatch relocation code and the s390
klp_write_module_reloc() function stub. They are no longer needed since
relocation work has been offloaded to module loader.
Signed-off-by: Jessica Yu <redacted>
---
arch/s390/include/asm/livepatch.h | 7 --
arch/x86/include/asm/livepatch.h | 2 -
arch/x86/kernel/Makefile | 1 -
arch/x86/kernel/livepatch.c | 70 -------------------
include/linux/livepatch.h | 20 ------
kernel/livepatch/core.c | 140 +++++++++++++++++++++++---------------
6 files changed, 84 insertions(+), 156 deletions(-)
delete mode 100644 arch/x86/kernel/livepatch.c
@@ -1,70 +0,0 @@-/*- * livepatch.c - x86-specific Kernel Live Patching Core- *- * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com>- * Copyright (C) 2014 SUSE- *- * This program is free software; you can redistribute it and/or- * modify it under the terms of the GNU General Public License- * as published by the Free Software Foundation; either version 2- * of the License, or (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program; if not, see <http://www.gnu.org/licenses/>.- */--#include <linux/module.h>-#include <linux/uaccess.h>-#include <asm/elf.h>-#include <asm/livepatch.h>--/**- * klp_write_module_reloc() - write a relocation in a module- * @mod: module in which the section to be modified is found- * @type: ELF relocation type (see asm/elf.h)- * @loc: address that the relocation should be written to- * @value: relocation value (sym address + addend)- *- * This function writes a relocation to the specified location for- * a particular module.- */-int klp_write_module_reloc(struct module *mod, unsigned long type,- unsigned long loc, unsigned long value)-{- size_t size = 4;- unsigned long val;- unsigned long core = (unsigned long)mod->core_layout.base;- unsigned long core_size = mod->core_layout.size;-- switch (type) {- case R_X86_64_NONE:- return 0;- case R_X86_64_64:- val = value;- size = 8;- break;- case R_X86_64_32:- val = (u32)value;- break;- case R_X86_64_32S:- val = (s32)value;- break;- case R_X86_64_PC32:- val = (u32)(value - loc);- break;- default:- /* unsupported relocation type */- return -EINVAL;- }-- if (loc < core || loc >= core + core_size)- /* loc does not point to any symbol inside the module */- return -EINVAL;-- return probe_kernel_write((void *)loc, &val, size);-}
@@ -204,75 +219,87 @@ static int klp_find_object_symbol(const char *objname, const char *name,return-EINVAL;}-/*-*externalsymbolsarelocatedoutsidetheparentobject(wheretheparent-*objectiseithervmlinuxorthekmodbeingpatched).-*/-staticintklp_find_external_symbol(structmodule*pmod,constchar*name,-unsignedlong*addr)-{-conststructkernel_symbol*sym;--/* first, check if it's an exported symbol */-preempt_disable();-sym=find_symbol(name,NULL,NULL,true,true);-if(sym){-*addr=sym->value;-preempt_enable();-return0;+staticintklp_resolve_symbols(Elf_Shdr*relasec,structmodule*pmod)+{+inti,cnt,vmlinux,ret;+structklp_bufbufs={0};+Elf_Rela*relas;+Elf_Sym*sym;+char*symname;+unsignedlongsympos;++relas=(Elf_Rela*)relasec->sh_addr;+/* For each rela in this klp relocation section */+for(i=0;i<relasec->sh_size/sizeof(Elf_Rela);i++){+sym=pmod->core_kallsyms.symtab+ELF_R_SYM(relas[i].r_info);+if(sym->st_shndx!=SHN_LIVEPATCH)+return-EINVAL;++klp_clear_buf(&bufs);++/* Format: .klp.sym.objname.symbol_name,sympos */+symname=pmod->core_kallsyms.strtab+sym->st_name;+cnt=sscanf(symname,".klp.sym.%64[^.].%128[^,],%lu",+bufs.objname,bufs.symname,&sympos);+if(cnt!=3)+return-EINVAL;++/* klp_find_object_symbol() treats a NULL objname as vmlinux */+vmlinux=!strcmp(bufs.objname,"vmlinux");+ret=klp_find_object_symbol(vmlinux?NULL:bufs.objname,+bufs.symname,sympos,+(unsignedlong*)&sym->st_value);+if(ret)+returnret;}-preempt_enable();-/*-*Checkifit'sinanother.owithinthepatchmodule.Thisalso-*checksthattheexternalsymbolisunique.-*/-returnklp_find_object_symbol(pmod->name,name,0,addr);+return0;}staticintklp_write_object_relocations(structmodule*pmod,structklp_object*obj){-intret=0;-unsignedlongval;-structklp_reloc*reloc;+inti,cnt,ret=0;+constchar*objname,*secname;+structklp_bufbufs={0};+Elf_Shdr*sec;if(WARN_ON(!klp_is_object_loaded(obj)))return-EINVAL;-if(WARN_ON(!obj->relocs))-return-EINVAL;+objname=klp_is_module(obj)?obj->name:"vmlinux";module_disable_ro(pmod);+/* For each klp relocation section */+for(i=1;i<pmod->klp_info->hdr.e_shnum;i++){+sec=pmod->klp_info->sechdrs+i;+if(!(sec->sh_flags&SHF_RELA_LIVEPATCH))+continue;-for(reloc=obj->relocs;reloc->name;reloc++){-/* discover the address of the referenced symbol */-if(reloc->external){-if(reloc->sympos>0){-pr_err("non-zero sympos for external reloc symbol '%s' is not supported\n",-reloc->name);-ret=-EINVAL;-gotoout;-}-ret=klp_find_external_symbol(pmod,reloc->name,&val);-}else-ret=klp_find_object_symbol(obj->name,-reloc->name,-reloc->sympos,-&val);-if(ret)-gotoout;+klp_clear_buf(&bufs);-ret=klp_write_module_reloc(pmod,reloc->type,reloc->loc,-val+reloc->addend);-if(ret){-pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n",-reloc->name,val,ret);-gotoout;+/* Check if this klp relocation section belongs to obj */+secname=pmod->klp_info->secstrings+sec->sh_name;+cnt=sscanf(secname,".klp.rela.%64[^.]",bufs.objname);+if(cnt!=1){+ret=-EINVAL;+break;}++if(strcmp(bufs.objname,objname))+continue;++ret=klp_resolve_symbols(sec,pmod);+if(ret)+break;++ret=apply_relocate_add(pmod->klp_info->sechdrs,+pmod->core_kallsyms.strtab,+pmod->klp_info->symndx,i,pmod);+if(ret)+break;}-out:module_enable_ro(pmod);returnret;}
@@ -703,11 +730,9 @@ static int klp_init_object_loaded(struct klp_patch *patch,structklp_func*func;intret;-if(obj->relocs){-ret=klp_write_object_relocations(patch->mod,obj);-if(ret)-returnret;-}+ret=klp_write_object_relocations(patch->mod,obj);+if(ret)+returnret;klp_for_each_func(obj,func){ret=klp_find_object_symbol(obj->name,func->old_name,
@@ -842,6 +867,9 @@ int klp_register_patch(struct klp_patch *patch){intret;+if(!is_livepatch_module(patch->mod))+return-EINVAL;+if(!klp_initialized())return-ENODEV;
Mark the module as a livepatch module so that the module loader can
appropriately identify and initialize it.
Signed-off-by: Jessica Yu <redacted>
---
samples/livepatch/livepatch-sample.c | 1 +
1 file changed, 1 insertion(+)
@@ -0,0 +1,311 @@+===========================+Livepatch module Elf format+===========================++This document outlines the Elf format requirements that livepatch modules must follow.++-----------------+Table of Contents+-----------------+0. Background and motivation+1. Livepatch modinfo field+2. Livepatch relocation sections+ 2.1 What are livepatch relocation sections?+ 2.2 Livepatch relocation section format+ 2.2.1 Required flags+ 2.2.2 Required name format+ 2.2.3 Example livepatch relocation section names+ 2.2.4 Example `readelf --sections` output+ 2.2.5 Example `readelf --relocs` output+3. Livepatch symbols+ 3.1 What are livepatch symbols?+ 3.2 A livepatch module's symbol table+ 3.3 Livepatch symbol format+ 3.3.1 Required flags+ 3.3.2 Required name format+ 3.3.3 Example livepatch symbol names+ 3.3.4 Example `readelf --symbols` output+4. Symbol table and Elf section access++----------------------------+0. Background and motivation+----------------------------++Formerly, livepatch required separate architecture-specific code to write+relocations. However, arch-specific code to write relocations already+exists in the module loader, so this former approach produced redundant+code. So, instead of duplicating code and re-implementing what the module+loader can already do, livepatch leverages existing code in the module+loader to perform the all the arch-specific relocation work. Specifically,+livepatch reuses the apply_relocate_add() function in the module loader to+write relocations. The patch module Elf format described in this document+enables livepatch to be able to do this. The hope is that this will make+livepatch more easily portable to other architectures and reduce the amount+of arch-specific code required to port livepatch to a particular+architecture.++Since apply_relocate_add() requires access to a module's section header+table, symbol table, and relocation section indices, Elf information is+preserved for livepatch modules (see section 4). Livepatch manages its own+relocation sections and symbols, which are described in this document. The+Elf constants used to mark livepatch symbols and relocation sections were+selected from OS-specific ranges according to the definitions from glibc.++0.1 Why does livepatch need to write its own relocations?+---------------------------------------------------------+A typical livepatch module contains patched versions of functions that can+reference non-exported global symbols and non-included local symbols.+Relocations referencing these types of symbols cannot be left in as-is+since the kernel module loader cannot resolve them and will therefore+reject the livepatch module. Furthermore, we cannot apply relocations that+affect modules not yet loaded at patch module load time (e.g. a patch to a+driver that is not loaded). Formerly, livepatch solved this problem by+embedding special "dynrela" (dynamic rela) sections in the resulting patch+module Elf output. Using these dynrela sections, livepatch could resolve+symbols while taking into account its scope and what module the symbol+belongs to, and then manually apply the dynamic relocations. However this+approach required livepatch to supply arch-specific code in order to write+these relocations. In the new format, livepatch manages its own SHT_RELA+relocation sections in place of dynrela sections, and the symbols that the+relas reference are special livepatch symbols (see section 2 and 3). The+arch-specific livepatch relocation code is replaced by a call to+apply_relocate_add().++================================+PATCH MODULE FORMAT REQUIREMENTS+================================++--------------------------+1. Livepatch modinfo field+--------------------------++Livepatch modules are required to have the "livepatch" modinfo attribute.+See the sample livepatch module in samples/livepatch/ for how this is done.++Livepatch modules can be identified by users by using the 'modinfo' command+and looking for the presence of the "livepatch" field. This field is also+used by the kernel module loader to identify livepatch modules.++Example modinfo output:+-----------------------+% modinfo livepatch-meminfo.ko+filename: livepatch-meminfo.ko+livepatch: Y+license: GPL+depends:+vermagic: 4.3.0+ SMP mod_unload++--------------------------------+2. Livepatch relocation sections+--------------------------------++-------------------------------------------+2.1 What are livepatch relocation sections?+-------------------------------------------+A livepatch module manages its own Elf relocation sections to apply+relocations to modules as well as to the kernel (vmlinux) at the+appropriate time. For example, if a patch module patches a driver that is+not currently loaded, livepatch will apply the corresponding livepatch+relocation section(s) to the driver once it loads.++Each "object" (e.g. vmlinux, or a module) within a patch module may have+multiple livepatch relocation sections associated with it (e.g. patches to+multiple functions within the same object). There is a 1-1 correspondence+between a livepatch relocation section and the target section (usually the+text section of a function) to which the relocation(s) apply. It is+also possible for a livepatch module to have no livepatch relocation+sections, as in the case of the sample livepatch module (see+samples/livepatch).++Since Elf information is preserved for livepatch modules (see Section 4), a+livepatch relocation section can be applied simply by passing in the+appropriate section index to apply_relocate_add(), which then uses it to+access the relocation section and apply the relocations.++Every symbol referenced by a rela in a livepatch relocation section is a+livepatch symbol. These must be resolved before livepatch can call+apply_relocate_add(). See Section 3 for more information.++---------------------------------------+2.2 Livepatch relocation section format+---------------------------------------++2.2.1 Required flags+--------------------+Livepatch relocation sections must be marked with the SHF_RELA_LIVEPATCH+section flag. See include/uapi/linux/elf.h for the definition. The module+loader recognizes this flag and will avoid applying those relocation sections+at patch module load time. These sections must also be marked with SHF_ALLOC,+so that the module loader doesn't discard them on module load (i.e. they will+be copied into memory along with the other SHF_ALLOC sections).++2.2.2 Required name format+--------------------------+The name of a livepatch relocation section must conform to the following format:++.klp.rela.objname.section_name+^ ^^ ^ ^ ^+|________||_____| |__________|+ [A] [B] [C]++[A] The relocation section name is prefixed with the string ".klp.rela."+[B] The name of the object (i.e. "vmlinux" or name of module) to+ which the relocation section belongs follows immediately after the prefix.+[C] The actual name of the section to which this relocation section applies.++2.2.3 Example livepatch relocation section names:+-------------------------------------------------+.klp.rela.ext4.text.ext4_attr_store+.klp.rela.vmlinux.text.cmdline_proc_show++2.2.4 Example `readelf --sections` output for a patch+module that patches vmlinux and modules 9p, btrfs, ext4:+--------------------------------------------------------+ Section Headers:+ [Nr] Name Type Address Off Size ES Flg Lk Inf Al+ [ snip ]+ [29] .klp.rela.9p.text.caches.show RELA 0000000000000000 002d58 0000c0 18 AIo 64 9 8+ [30] .klp.rela.btrfs.text.btrfs.feature.attr.show RELA 0000000000000000 002e18 000060 18 AIo 64 11 8+ [ snip ]+ [34] .klp.rela.ext4.text.ext4.attr.store RELA 0000000000000000 002fd8 0000d8 18 AIo 64 13 8+ [35] .klp.rela.ext4.text.ext4.attr.show RELA 0000000000000000 0030b0 000150 18 AIo 64 15 8+ [36] .klp.rela.vmlinux.text.cmdline.proc.show RELA 0000000000000000 003200 000018 18 AIo 64 17 8+ [37] .klp.rela.vmlinux.text.meminfo.proc.show RELA 0000000000000000 003218 0000f0 18 AIo 64 19 8+ [ snip ] ^ ^+ | |+ [*] [*]+[*] Livepatch relocation sections are SHT_RELA sections but with a few special+characteristics. Notice that they are marked SHF_ALLOC ("A") so that they will+not be discarded when the module is loaded into memory, as well as with the+SHF_RELA_LIVEPATCH flag ("o" - for OS-specific).++2.2.5 Example `readelf --relocs` output for a patch module:+-----------------------------------------------------------+Relocation section '.klp.rela.btrfs.text.btrfs_feature_attr_show' at offset 0x2ba0 contains 4 entries:+ Offset Info Type Symbol's Value Symbol's Name + Addend+000000000000001f 0000005e00000002 R_X86_64_PC32 0000000000000000 .klp.sym.vmlinux.printk,0 - 4+0000000000000028 0000003d0000000b R_X86_64_32S 0000000000000000 .klp.sym.btrfs.btrfs_ktype,0 + 0+0000000000000036 0000003b00000002 R_X86_64_PC32 0000000000000000 .klp.sym.btrfs.can_modify_feature.isra.3,0 - 4+000000000000004c 0000004900000002 R_X86_64_PC32 0000000000000000 .klp.sym.vmlinux.snprintf,0 - 4+[ snip ] ^+ |+ [*]+[*] Every symbol referenced by a relocation is a livepatch symbol.++--------------------+3. Livepatch symbols+--------------------++-------------------------------+3.1 What are livepatch symbols?+-------------------------------+Livepatch symbols are symbols referred to by livepatch relocation sections.+These are symbols accessed from new versions of functions for patched+objects, whose addresses cannot be resolved by the module loader (because+they are local or unexported global syms). Since the module loader only+resolves exported syms, and not every symbol referenced by the new patched+functions is exported, livepatch symbols were introduced. They are used+also in cases where we cannot immediately know the address of a symbol when+a patch module loads. For example, this is the case when livepatch patches+a module that is not loaded yet. In this case, the relevant livepatch+symbols are resolved simply when the target module loads. In any case, for+any livepatch relocation section, all livepatch symbols referenced by that+section must be resolved before livepatch can call apply_relocate_add() for+that reloc section.++Livepatch symbols must be marked with SHN_LIVEPATCH so that the module+loader can identify and ignore them. Livepatch modules keep these symbols+in their symbol tables, and the symbol table is made accessible through+module->symtab.++-------------------------------------+3.2 A livepatch module's symbol table+-------------------------------------+Normally, a stripped down copy of a module's symbol table (containing only+"core" symbols) is made available through module->symtab (See layout_symtab()+in kernel/module.c). For livepatch modules, the symbol table copied into memory+on module load must be exactly the same as the symbol table produced when the+patch module was compiled. This is because the relocations in each livepatch+relocation section refer to their respective symbols with their symbol indices,+and the original symbol indices (and thus the symtab ordering) must be+preserved in order for apply_relocate_add() to find the right symbol.++For example, take this particular rela from a livepatch module:+Relocation section '.klp.rela.btrfs.text.btrfs_feature_attr_show' at offset 0x2ba0 contains 4 entries:+ Offset Info Type Symbol's Value Symbol's Name + Addend+000000000000001f 0000005e00000002 R_X86_64_PC32 0000000000000000 .klp.sym.vmlinux.printk,0 - 4++This rela refers to the symbol '.klp.sym.vmlinux.printk,0', and the symbol index is encoded+in 'Info'. Here its symbol index is 0x5e, which is 94 in decimal, which refers to the+symbol index 94.+And in this patch module's corresponding symbol table, symbol index 94 refers to that very symbol:+[ snip ]+94: 0000000000000000 0 NOTYPE GLOBAL DEFAULT OS [0xff20] .klp.sym.vmlinux.printk,0+[ snip ]++---------------------------+3.3 Livepatch symbol format+---------------------------++3.3.1 Required flags+--------------------+Livepatch symbols must have their section index marked as SHN_LIVEPATCH, so+that the module loader can identify them and not attempt to resolve them.+See include/uapi/linux/elf.h for the actual definitions.++3.3.2 Required name format+--------------------------+Livepatch symbol names must conform to the following format:++.klp.sym.objname.symbol_name,sympos+^ ^^ ^ ^ ^ ^+|_______||_____| |_________| |+ [A] [B] [C] [D]++[A] The symbol name is prefixed with the string ".klp.sym."+[B] The name of the object (i.e. "vmlinux" or name of module) to+ which the symbol belongs follows immediately after the prefix.+[C] The actual name of the symbol.+[D] The position of the symbol in the object (as according to kallsyms)+ This is used to differentiate duplicate symbols within the same+ object. The symbol position is expressed numerically (0, 1, 2...).+ The symbol position of a unique symbol is 0.++3.3.3 Example livepatch symbol names:+-------------------------------------+.klp.sym.vmlinux.snprintf,0+.klp.sym.vmlinux.printk,0+.klp.sym.btrfs.btrfs_ktype,0++3.3.4 Example `readelf --symbols` output for a patch module:+------------------------------------------------------------+Symbol table '.symtab' contains 127 entries:+ Num: Value Size Type Bind Vis Ndx Name+ [ snip ]+ 73: 0000000000000000 0 NOTYPE GLOBAL DEFAULT OS [0xff20] .klp.sym.vmlinux.snprintf,0+ 74: 0000000000000000 0 NOTYPE GLOBAL DEFAULT OS [0xff20] .klp.sym.vmlinux.capable,0+ 75: 0000000000000000 0 NOTYPE GLOBAL DEFAULT OS [0xff20] .klp.sym.vmlinux.find_next_bit,0+ 76: 0000000000000000 0 NOTYPE GLOBAL DEFAULT OS [0xff20] .klp.sym.vmlinux.si_swapinfo,0+ [ snip ] ^+ |+ [*]+[*] Note that the 'Ndx' (Section index) for these symbols is SHN_LIVEPATCH (0xff20).+ "OS" means OS-specific.++--------------------------------------+4. Symbol table and Elf section access+--------------------------------------+A livepatch module's symbol table is accessible through module->symtab.++Since apply_relocate_add() requires access to a module's section headers,+symbol table, and relocation section indices, Elf information is preserved for+livepatch modules and is made accessible by the module loader through+module->klp_info, which is a klp_modinfo struct. When a livepatch module loads,+this struct is filled in by the module loader. Its fields are documented below:++struct klp_modinfo {+ Elf_Ehdr hdr; /* Elf header */+ Elf_Shdr *sechdrs; /* Section header table */+ char *secstrings; /* String table for the section headers */+ unsigned int symndx; /* The symbol table section index */+};
From: kbuild test robot <hidden> Date: 2016-03-16 20:26:16
Hi Jessica,
[auto build test ERROR on s390/features]
[also build test ERROR on v4.5 next-20160316]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Jessica-Yu/mostly-Arch-independent-livepatch/20160317-035230
base: https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git features
config: x86_64-randconfig-x016-201611 (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All error/warnings (new ones prefixed by >>):
In file included from include/linux/kernel.h:13:0,
from include/linux/list.h:8,
from include/linux/module.h:9,
from include/linux/moduleloader.h:5,
from kernel/module.c:20:
kernel/module.c: In function 'find_livepatch_modinfo':
quoted
kernel/module.c:2767:10: error: expected ')' before 'mod'
mod->name);
^
include/linux/printk.h:236:21: note: in definition of macro 'pr_fmt'
#define pr_fmt(fmt) fmt
^
quoted
kernel/module.c:2766:3: note: in expansion of macro 'pr_err'
pr_err("%s: module is marked as livepatch module, but livepatch support is disabled"
^
In file included from include/linux/printk.h:6:0,
from include/linux/kernel.h:13,
from include/linux/list.h:8,
from include/linux/module.h:9,
from include/linux/moduleloader.h:5,
from kernel/module.c:20:
quoted
include/linux/kern_levels.h:4:18: warning: format '%s' expects a matching 'char *' argument [-Wformat=]
#define KERN_SOH "\001" /* ASCII Start Of Header */
^
include/linux/kern_levels.h:10:18: note: in expansion of macro 'KERN_SOH'
#define KERN_ERR KERN_SOH "3" /* error conditions */
^
include/linux/printk.h:252:9: note: in expansion of macro 'KERN_ERR'
printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
^
quoted
kernel/module.c:2766:3: note: in expansion of macro 'pr_err'
pr_err("%s: module is marked as livepatch module, but livepatch support is disabled"
^
vim +2767 kernel/module.c
2760 return 0;
2761 }
2762 #else /* !CONFIG_LIVEPATCH */
2763 static int find_livepatch_modinfo(struct module *mod, struct load_info *info)
2764 {
2765 if (get_modinfo(info, "livepatch")) {
2766 pr_err("%s: module is marked as livepatch module, but livepatch support is disabled"
2767 mod->name);
From: kbuild test robot <hidden> Date: 2016-03-16 20:29:15
Hi Jessica,
[auto build test WARNING on s390/features]
[also build test WARNING on v4.5 next-20160316]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Jessica-Yu/mostly-Arch-independent-livepatch/20160317-035230
base: https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git features
config: xtensa-allyesconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=xtensa
All warnings (new ones prefixed by >>):
In file included from include/linux/kernel.h:13:0,
from include/linux/list.h:8,
from include/linux/module.h:9,
from include/linux/moduleloader.h:5,
from kernel/module.c:20:
kernel/module.c: In function 'find_livepatch_modinfo':
kernel/module.c:2767:10: error: expected ')' before 'mod'
mod->name);
^
include/linux/printk.h:236:21: note: in definition of macro 'pr_fmt'
#define pr_fmt(fmt) fmt
^
kernel/module.c:2766:3: note: in expansion of macro 'pr_err'
pr_err("%s: module is marked as livepatch module, but livepatch support is disabled"
^
quoted
kernel/module.c:2767:10: warning: format '%s' expects a matching 'char *' argument [-Wformat=]
mod->name);
^
include/linux/printk.h:236:21: note: in definition of macro 'pr_fmt'
#define pr_fmt(fmt) fmt
^
kernel/module.c:2766:3: note: in expansion of macro 'pr_err'
pr_err("%s: module is marked as livepatch module, but livepatch support is disabled"
^
vim +2767 kernel/module.c
2751 } while (len);
2752 return 0;
2753 }
2754
2755 #ifdef CONFIG_LIVEPATCH
2756 static int find_livepatch_modinfo(struct module *mod, struct load_info *info)
2757 {
2758 mod->klp = get_modinfo(info, "livepatch") ? true : false;
2759
2760 return 0;
2761 }
2762 #else /* !CONFIG_LIVEPATCH */
2763 static int find_livepatch_modinfo(struct module *mod, struct load_info *info)
2764 {
2765 if (get_modinfo(info, "livepatch")) {
2766 pr_err("%s: module is marked as livepatch module, but livepatch support is disabled"
2767 mod->name);
2768 return -ENOEXEC;
2769 }
2770
2771 return 0;
2772 }
2773 #endif /* CONFIG_LIVEPATCH */
2774
2775 /* Sets info->hdr and info->len. */
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
For livepatch modules, copy Elf section, symbol, and string information
from the load_info struct in the module loader. Persist copies of the
original symbol table and string table.
Livepatch manages its own relocation sections in order to reuse module
loader code to write relocations. Livepatch modules must preserve Elf
information such as section indices in order to apply livepatch relocation
sections using the module loader's apply_relocate_add() function.
In order to apply livepatch relocation sections, livepatch modules must
keep a complete copy of their original symbol table in memory. Normally, a
stripped down copy of a module's symbol table (containing only "core"
symbols) is made available through module->core_symtab. But for livepatch
modules, the symbol table copied into memory on module load must be exactly
the same as the symbol table produced when the patch module was compiled.
This is because the relocations in each livepatch relocation section refer
to their respective symbols with their symbol indices, and the original
symbol indices (and thus the symtab ordering) must be preserved in order
for apply_relocate_add() to find the right symbol.
Signed-off-by: Jessica Yu <redacted>
---
include/linux/module.h | 25 ++++++++++
kernel/module.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 146 insertions(+), 2 deletions(-)
/* Free any allocated parameters. */
destroy_params(mod->kp, mod->num_kp);
+ if (is_livepatch_module(mod))
+ free_module_elf(mod);
+
/* Now we can delete it from the lists */
mutex_lock(&module_mutex);
/* Unlink carefully: kallsyms could be walking list. */
(long)sym[i].st_value);
break;
+ case SHN_LIVEPATCH:
+ /* Livepatch symbols are resolved by livepatch */
+ break;
+
case SHN_UNDEF:
ksym = resolve_symbol_wait(mod, info, name);
/* Ok if resolved. */
/* Compute total space required for the core symbols' strtab. */
for (ndst = i = 0; i < nsrc; i++) {
- if (i == 0 ||
+ if (i == 0 || is_livepatch_module(mod) ||
is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
info->index.pcpu)) {
strtab_size += strlen(&info->strtab[src[i].st_name])+1;
mod->core_kallsyms.strtab = s = mod->core_layout.base + info->stroffs;
src = mod->kallsyms->symtab;
for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
- if (i == 0 ||
+ if (i == 0 || is_livepatch_module(mod) ||
is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum,
info->index.pcpu)) {
dst[ndst] = src[i];
@@ -2665,6 +2752,26 @@ static int copy_chunked_from_user(void *dst, const void __user *usrc, unsigned l
return 0;
}
+#ifdef CONFIG_LIVEPATCH
+static int find_livepatch_modinfo(struct module *mod, struct load_info *info)
+{
+ mod->klp = get_modinfo(info, "livepatch") ? true : false;
+
+ return 0;
+}
+#else /* !CONFIG_LIVEPATCH */
+static int find_livepatch_modinfo(struct module *mod, struct load_info *info)
+{
+ if (get_modinfo(info, "livepatch")) {
+ pr_err("%s: module is marked as livepatch module, but livepatch support is disabled"
+ mod->name);
...And that is why I should have tested the changes with !CONFIG_LIVEPATCH
before sending this out. :-\ The above line should've been (w/ comma and newline):
pr_err("%s: module is marked as livepatch module, but livepatch support is disabled\n",
mod->name);
Jessica
From: Miroslav Benes <mbenes@suse.cz> Date: 2016-03-21 13:47:08
On Wed, 16 Mar 2016, Jessica Yu wrote:
Livepatch manages its own relocation sections and symbols in order to be
able to reuse module loader code to write relocations. This removes
livepatch's dependence on separate "dynrela" sections to write relocations
and also allows livepatch to patch modules that are not yet loaded.
The livepatch Elf relocation section flag (SHF_RELA_LIVEPATCH),
and symbol section index (SHN_LIVEPATCH) allow both livepatch and the
module loader to identity livepatch relocation sections and livepatch
symbols.
Livepatch relocation sections are marked with SHF_RELA_LIVEPATCH to
indicate to the module loader that it should not apply that relocation
section and that livepatch will handle them.
The SHN_LIVEPATCH shndx marks symbols that will be resolved by livepatch.
The module loader ignores these symbols and does not attempt to resolve
them.
The values of these Elf constants were selected from OS-specific
ranges according to the definitions from glibc.
Signed-off-by: Jessica Yu <redacted>
From: Miroslav Benes <mbenes@suse.cz> Date: 2016-03-21 13:49:04
On Wed, 16 Mar 2016, Jessica Yu wrote:
For livepatch modules, copy Elf section, symbol, and string information
from the load_info struct in the module loader. Persist copies of the
original symbol table and string table.
Livepatch manages its own relocation sections in order to reuse module
loader code to write relocations. Livepatch modules must preserve Elf
information such as section indices in order to apply livepatch relocation
sections using the module loader's apply_relocate_add() function.
In order to apply livepatch relocation sections, livepatch modules must
keep a complete copy of their original symbol table in memory. Normally, a
stripped down copy of a module's symbol table (containing only "core"
symbols) is made available through module->core_symtab. But for livepatch
modules, the symbol table copied into memory on module load must be exactly
the same as the symbol table produced when the patch module was compiled.
This is because the relocations in each livepatch relocation section refer
to their respective symbols with their symbol indices, and the original
symbol indices (and thus the symtab ordering) must be preserved in order
for apply_relocate_add() to find the right symbol.
Signed-off-by: Jessica Yu <redacted>
With a fix for a bug reported by kbuild test robot
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
From: Miroslav Benes <mbenes@suse.cz> Date: 2016-03-21 13:49:18
On Wed, 16 Mar 2016, Jessica Yu wrote:
Livepatch needs to utilize the symbol information contained in the
mod_arch_specific struct in order to be able to call the s390
apply_relocate_add() function to apply relocations. Keep a reference to
syminfo if the module is a livepatch module. Remove the redundant vfree()
in module_finalize() since module_arch_freeing_init() (which also frees
those structures) is called in do_init_module(). If the module isn't a
livepatch module, we free the structures in module_arch_freeing_init() as
usual.
Signed-off-by: Jessica Yu <redacted>
I think it is better to make this KSYM_NAME_LEN. KSYM_SYMBOL_LEN looks
like something different and KSYM_NAME_LEN is 128 which you reference
below.
+ char objname[MODULE_NAME_LEN];
+};
[...]
+static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod)
+{
+ int i, cnt, vmlinux, ret;
+ struct klp_buf bufs = {0};
+ Elf_Rela *relas;
+ Elf_Sym *sym;
+ char *symname;
+ unsigned long sympos;
+
+ relas = (Elf_Rela *) relasec->sh_addr;
+ /* For each rela in this klp relocation section */
+ for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
+ sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info);
+ if (sym->st_shndx != SHN_LIVEPATCH)
+ return -EINVAL;
+
+ klp_clear_buf(&bufs);
+
+ /* Format: .klp.sym.objname.symbol_name,sympos */
+ symname = pmod->core_kallsyms.strtab + sym->st_name;
+ cnt = sscanf(symname, ".klp.sym.%64[^.].%128[^,],%lu",
+ bufs.objname, bufs.symname, &sympos);
It would be really nice to change actual values for their macro
definitions, but this would be a mess which is not worth it. Anyway
shouldn't those width modifiers be %63 and %127 to make a room for \0?
+ if (cnt != 3)
+ return -EINVAL;
+
+ /* klp_find_object_symbol() treats a NULL objname as vmlinux */
+ vmlinux = !strcmp(bufs.objname, "vmlinux");
+ ret = klp_find_object_symbol(vmlinux ? NULL : bufs.objname,
+ bufs.symname, sympos,
+ (unsigned long *) &sym->st_value);
+ if (ret)
+ return ret;
}
- preempt_enable();
- /*
- * Check if it's in another .o within the patch module. This also
- * checks that the external symbol is unique.
- */
- return klp_find_object_symbol(pmod->name, name, 0, addr);
+ return 0;
}
static int klp_write_object_relocations(struct module *pmod,
struct klp_object *obj)
{
- int ret = 0;
- unsigned long val;
- struct klp_reloc *reloc;
+ int i, cnt, ret = 0;
+ const char *objname, *secname;
+ struct klp_buf bufs = {0};
+ Elf_Shdr *sec;
if (WARN_ON(!klp_is_object_loaded(obj)))
return -EINVAL;
- if (WARN_ON(!obj->relocs))
- return -EINVAL;
+ objname = klp_is_module(obj) ? obj->name : "vmlinux";
module_disable_ro(pmod);
+ /* For each klp relocation section */
+ for (i = 1; i < pmod->klp_info->hdr.e_shnum; i++) {
+ sec = pmod->klp_info->sechdrs + i;
+ if (!(sec->sh_flags & SHF_RELA_LIVEPATCH))
+ continue;
- for (reloc = obj->relocs; reloc->name; reloc++) {
- /* discover the address of the referenced symbol */
- if (reloc->external) {
- if (reloc->sympos > 0) {
- pr_err("non-zero sympos for external reloc symbol '%s' is not supported\n",
- reloc->name);
- ret = -EINVAL;
- goto out;
- }
- ret = klp_find_external_symbol(pmod, reloc->name, &val);
- } else
- ret = klp_find_object_symbol(obj->name,
- reloc->name,
- reloc->sympos,
- &val);
- if (ret)
- goto out;
+ klp_clear_buf(&bufs);
- ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc,
- val + reloc->addend);
- if (ret) {
- pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n",
- reloc->name, val, ret);
- goto out;
+ /* Check if this klp relocation section belongs to obj */
+ secname = pmod->klp_info->secstrings + sec->sh_name;
+ cnt = sscanf(secname, ".klp.rela.%64[^.]", bufs.objname);
Same here.
Otherwise it looks really good (which applies for the whole series), so
after fixing these nits you can add my
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Cheers,
Miroslav
On Wed, Mar 16, 2016 at 03:47:04PM -0400, Jessica Yu wrote:
quoted hunk
For livepatch modules, copy Elf section, symbol, and string information
from the load_info struct in the module loader. Persist copies of the
original symbol table and string table.
Livepatch manages its own relocation sections in order to reuse module
loader code to write relocations. Livepatch modules must preserve Elf
information such as section indices in order to apply livepatch relocation
sections using the module loader's apply_relocate_add() function.
In order to apply livepatch relocation sections, livepatch modules must
keep a complete copy of their original symbol table in memory. Normally, a
stripped down copy of a module's symbol table (containing only "core"
symbols) is made available through module->core_symtab. But for livepatch
modules, the symbol table copied into memory on module load must be exactly
the same as the symbol table produced when the patch module was compiled.
This is because the relocations in each livepatch relocation section refer
to their respective symbols with their symbol indices, and the original
symbol indices (and thus the symtab ordering) must be preserved in order
for apply_relocate_add() to find the right symbol.
Signed-off-by: Jessica Yu <redacted>
---
include/linux/module.h | 25 ++++++++++
kernel/module.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 146 insertions(+), 2 deletions(-)
@@ -456,7 +465,11 @@ struct module {#endif#ifdef CONFIG_LIVEPATCH+boolklp;/* Is this a livepatch module? */boolklp_alive;++/* Elf information */+structklp_modinfo*klp_info;#endif#ifdef CONFIG_MODULE_UNLOAD
@@ -630,6 +643,18 @@ static inline bool module_requested_async_probing(struct module *module)returnmodule&&module->async_probe_requested;}+#ifdef CONFIG_LIVEPATCH+staticinlineboolis_livepatch_module(structmodule*mod)+{+returnmod->klp;+}+#else /* !CONFIG_LIVEPATCH */+staticinlineboolis_livepatch_module(structmodule*mod)+{+returnfalse;+}+#endif /* CONFIG_LIVEPATCH */+#else /* !CONFIG_MODULES... *//* Given an address, look for it in the exception tables. */
+
+ /*
+ * For livepatch modules, core_symtab is a complete copy
s/core_symtab/core_kallsyms.symtab/ ?
+ * of the original symbol table. Adjust sh_addr to point
+ * to core_symtab since the copy of the symtab in module
+ * init memory is freed at the end of do_init_module().
+ */
+ mod->klp_info->sechdrs[symndx].sh_addr = (unsigned long) mod->core_kallsyms.symtab;
On Wed, Mar 16, 2016 at 03:47:06PM -0400, Jessica Yu wrote:
quoted hunk
Reuse module loader code to write relocations, thereby eliminating the need
for architecture specific relocation code in livepatch. Specifically, reuse
the apply_relocate_add() function in the module loader to write relocations
instead of duplicating functionality in livepatch's arch-dependent
klp_write_module_reloc() function.
In order to accomplish this, livepatch modules manage their own relocation
sections (marked with the SHF_RELA_LIVEPATCH section flag) and
livepatch-specific symbols (marked with SHN_LIVEPATCH symbol section
index). To apply livepatch relocation sections, livepatch symbols
referenced by relocs are resolved and then apply_relocate_add() is called
to apply those relocations.
In addition, remove x86 livepatch relocation code and the s390
klp_write_module_reloc() function stub. They are no longer needed since
relocation work has been offloaded to module loader.
Signed-off-by: Jessica Yu <redacted>
---
arch/s390/include/asm/livepatch.h | 7 --
arch/x86/include/asm/livepatch.h | 2 -
arch/x86/kernel/Makefile | 1 -
arch/x86/kernel/livepatch.c | 70 -------------------
include/linux/livepatch.h | 20 ------
kernel/livepatch/core.c | 140 +++++++++++++++++++++++---------------
6 files changed, 84 insertions(+), 156 deletions(-)
delete mode 100644 arch/x86/kernel/livepatch.c
@@ -1,70 +0,0 @@-/*- * livepatch.c - x86-specific Kernel Live Patching Core- *- * Copyright (C) 2014 Seth Jennings <sjenning-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>- * Copyright (C) 2014 SUSE- *- * This program is free software; you can redistribute it and/or- * modify it under the terms of the GNU General Public License- * as published by the Free Software Foundation; either version 2- * of the License, or (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program; if not, see <http://www.gnu.org/licenses/>.- */--#include <linux/module.h>-#include <linux/uaccess.h>-#include <asm/elf.h>-#include <asm/livepatch.h>--/**- * klp_write_module_reloc() - write a relocation in a module- * @mod: module in which the section to be modified is found- * @type: ELF relocation type (see asm/elf.h)- * @loc: address that the relocation should be written to- * @value: relocation value (sym address + addend)- *- * This function writes a relocation to the specified location for- * a particular module.- */-int klp_write_module_reloc(struct module *mod, unsigned long type,- unsigned long loc, unsigned long value)-{- size_t size = 4;- unsigned long val;- unsigned long core = (unsigned long)mod->core_layout.base;- unsigned long core_size = mod->core_layout.size;-- switch (type) {- case R_X86_64_NONE:- return 0;- case R_X86_64_64:- val = value;- size = 8;- break;- case R_X86_64_32:- val = (u32)value;- break;- case R_X86_64_32S:- val = (s32)value;- break;- case R_X86_64_PC32:- val = (u32)(value - loc);- break;- default:- /* unsupported relocation type */- return -EINVAL;- }-- if (loc < core || loc >= core + core_size)- /* loc does not point to any symbol inside the module */- return -EINVAL;-- return probe_kernel_write((void *)loc, &val, size);-}
@@ -204,75 +219,87 @@ static int klp_find_object_symbol(const char *objname, const char *name,return-EINVAL;}-/*-*externalsymbolsarelocatedoutsidetheparentobject(wheretheparent-*objectiseithervmlinuxorthekmodbeingpatched).-*/-staticintklp_find_external_symbol(structmodule*pmod,constchar*name,-unsignedlong*addr)-{-conststructkernel_symbol*sym;--/* first, check if it's an exported symbol */-preempt_disable();-sym=find_symbol(name,NULL,NULL,true,true);-if(sym){-*addr=sym->value;-preempt_enable();-return0;+staticintklp_resolve_symbols(Elf_Shdr*relasec,structmodule*pmod)+{+inti,cnt,vmlinux,ret;+structklp_bufbufs={0};+Elf_Rela*relas;+Elf_Sym*sym;+char*symname;+unsignedlongsympos;++relas=(Elf_Rela*)relasec->sh_addr;+/* For each rela in this klp relocation section */+for(i=0;i<relasec->sh_size/sizeof(Elf_Rela);i++){+sym=pmod->core_kallsyms.symtab+ELF_R_SYM(relas[i].r_info);+if(sym->st_shndx!=SHN_LIVEPATCH)+return-EINVAL;
Probably a good idea to print a useful error here (and in any other
place with an original error condition).
+
+ klp_clear_buf(&bufs);
I think using the klp_buf struct to group these variables adds some
unnecessary obfuscation. As does wrapping memset in another function.
And the 'klp_buf' name doesn't really describe the purpose of the
struct. So I'd vote to just get rid of the struct and keep the buffers
in separate variables, and just call memset() directly.
Also is it even necessary to clear the buffers? sscanf() seems to add
NULL termination anyway.
Hard-coding the buffer sizes in the sscanf format string is less than
ideal because the defines could conceivably change. How about something
like:
char objname[MODULE_NAME_LEN+1];
char symname[KSYM_NAME_LEN+1];
...
cnt = sscanf(symname,
".klp.sym.%" __stringify(MODULE_NAME_LEN)
"[^.].%" __stringify(KSYM_NAME_LEN)
"[^,],%lu", bufs.objname, bufs.symname, &sympos);
(I couldn't figure out a way to stringify (MODULE_NAME_LEN-1), so
instead I made the buffers 1 byte larger.)
+ if (cnt != 3)
+ return -EINVAL;
+
+ /* klp_find_object_symbol() treats a NULL objname as vmlinux */
+ vmlinux = !strcmp(bufs.objname, "vmlinux");
+ ret = klp_find_object_symbol(vmlinux ? NULL : bufs.objname,
+ bufs.symname, sympos,
+ (unsigned long *) &sym->st_value);
Is it safe to assume that "unsigned long" is always the same size as
st_value for all architectures? If not, passing the st_value pointer to
klp_find_object_symbol() could be dangerous: it could misalign the data
or even write past the variable.
I think it would be safer to pass a temporary unsigned long variable to
klp_find_object_symbol(). Then it can be manually assigned to st_value.
Worst case it would be truncated (though in practice I doubt that could
really happen).
--
Josh
On Wed, Mar 16, 2016 at 03:47:07PM -0400, Jessica Yu wrote:
quoted hunk
Mark the module as a livepatch module so that the module loader can
appropriately identify and initialize it.
Signed-off-by: Jessica Yu <redacted>
---
samples/livepatch/livepatch-sample.c | 1 +
1 file changed, 1 insertion(+)
This patch should probably either be before the previous patch in the
series, or just squashed into it. Otherwise the sample module could
fail to work between the two commits and could break bisectability.
--
Josh
From: Petr Mladek <pmladek@suse.com> Date: 2016-03-21 16:32:03
On Wed 2016-03-16 15:47:06, Jessica Yu wrote:
Reuse module loader code to write relocations, thereby eliminating the need
for architecture specific relocation code in livepatch. Specifically, reuse
the apply_relocate_add() function in the module loader to write relocations
instead of duplicating functionality in livepatch's arch-dependent
klp_write_module_reloc() function.
In order to accomplish this, livepatch modules manage their own relocation
sections (marked with the SHF_RELA_LIVEPATCH section flag) and
livepatch-specific symbols (marked with SHN_LIVEPATCH symbol section
index). To apply livepatch relocation sections, livepatch symbols
referenced by relocs are resolved and then apply_relocate_add() is called
to apply those relocations.
In addition, remove x86 livepatch relocation code and the s390
klp_write_module_reloc() function stub. They are no longer needed since
relocation work has been offloaded to module loader.
Most of the problems were covered by Mirek and Josh. I agree with
them. Please read two more comments below.
quoted hunk
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.cindex 780f00c..2aa20fa 100644--- a/kernel/livepatch/core.c+++ b/kernel/livepatch/core.c
+static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod)
+{
+ int i, cnt, vmlinux, ret;
+ struct klp_buf bufs = {0};
+ Elf_Rela *relas;
+ Elf_Sym *sym;
+ char *symname;
+ unsigned long sympos;
+
+ relas = (Elf_Rela *) relasec->sh_addr;
+ /* For each rela in this klp relocation section */
+ for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
+ sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info);
+ if (sym->st_shndx != SHN_LIVEPATCH)
+ return -EINVAL;
+
+ klp_clear_buf(&bufs);
+
+ /* Format: .klp.sym.objname.symbol_name,sympos */
+ symname = pmod->core_kallsyms.strtab + sym->st_name;
+ cnt = sscanf(symname, ".klp.sym.%64[^.].%128[^,],%lu",
+ bufs.objname, bufs.symname, &sympos);
Note that MODULE_NAME_LEN even is not 64. It is defined by:
#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
I strongly suggest to use the proposal from Josh.
+ if (cnt != 3)
+ return -EINVAL;
+
+ /* klp_find_object_symbol() treats a NULL objname as vmlinux */
+ vmlinux = !strcmp(bufs.objname, "vmlinux");
+ ret = klp_find_object_symbol(vmlinux ? NULL : bufs.objname,
+ bufs.symname, sympos,
+ (unsigned long *) &sym->st_value);
+ if (ret)
+ return ret;
}
- preempt_enable();
- /*
- * Check if it's in another .o within the patch module. This also
- * checks that the external symbol is unique.
- */
- return klp_find_object_symbol(pmod->name, name, 0, addr);
+ return 0;
}
[...]
quoted hunk
@@ -842,6 +867,9 @@ int klp_register_patch(struct klp_patch *patch) { int ret;+ if (!is_livepatch_module(patch->mod))+ return -EINVAL;+
This breaks bisectability if livepatch-sample is used. Please, merge
the 5th patch here or move it before this one.
Best Regards,
Petr
On Mon, Mar 21, 2016 at 05:31:57PM +0100, Petr Mladek wrote:
quoted
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.cindex 780f00c..2aa20fa 100644--- a/kernel/livepatch/core.c+++ b/kernel/livepatch/core.c
+static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod)
+{
+ int i, cnt, vmlinux, ret;
+ struct klp_buf bufs = {0};
+ Elf_Rela *relas;
+ Elf_Sym *sym;
+ char *symname;
+ unsigned long sympos;
+
+ relas = (Elf_Rela *) relasec->sh_addr;
+ /* For each rela in this klp relocation section */
+ for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
+ sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info);
+ if (sym->st_shndx != SHN_LIVEPATCH)
+ return -EINVAL;
+
+ klp_clear_buf(&bufs);
+
+ /* Format: .klp.sym.objname.symbol_name,sympos */
+ symname = pmod->core_kallsyms.strtab + sym->st_name;
+ cnt = sscanf(symname, ".klp.sym.%64[^.].%128[^,],%lu",
+ bufs.objname, bufs.symname, &sympos);
Note that MODULE_NAME_LEN even is not 64. It is defined by:
#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
I strongly suggest to use the proposal from Josh.
Hm, looks like my suggestion to use __stringify(MODULE_NAME_LEN) doesn't
work. It results in the string "MODULE_NAME_LEN". Which surprises me:
isn't is supposed to resolve the macro before applying the '#' operation
to it?
I was going to suggest another idea: hard-code it at 63 and then do
something like
BUILD_BUG_ON(MODULE_NAME_LEN != 64)
But you're right... it's not even 64!
Need to think on this some more...
--
Josh
From: Petr Mladek <pmladek@suse.com> Date: 2016-03-21 16:50:47
On Wed 2016-03-16 15:47:04, Jessica Yu wrote:
quoted hunk
For livepatch modules, copy Elf section, symbol, and string information
from the load_info struct in the module loader. Persist copies of the
original symbol table and string table.
Livepatch manages its own relocation sections in order to reuse module
loader code to write relocations. Livepatch modules must preserve Elf
information such as section indices in order to apply livepatch relocation
sections using the module loader's apply_relocate_add() function.
In order to apply livepatch relocation sections, livepatch modules must
keep a complete copy of their original symbol table in memory. Normally, a
stripped down copy of a module's symbol table (containing only "core"
symbols) is made available through module->core_symtab. But for livepatch
modules, the symbol table copied into memory on module load must be exactly
the same as the symbol table produced when the patch module was compiled.
This is because the relocations in each livepatch relocation section refer
to their respective symbols with their symbol indices, and the original
symbol indices (and thus the symtab ordering) must be preserved in order
for apply_relocate_add() to find the right symbol.
Signed-off-by: Jessica Yu <redacted>
On Mon, Mar 21, 2016 at 11:46:51AM -0500, Josh Poimboeuf wrote:
On Mon, Mar 21, 2016 at 05:31:57PM +0100, Petr Mladek wrote:
quoted
quoted
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.cindex 780f00c..2aa20fa 100644--- a/kernel/livepatch/core.c+++ b/kernel/livepatch/core.c
+static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod)
+{
+ int i, cnt, vmlinux, ret;
+ struct klp_buf bufs = {0};
+ Elf_Rela *relas;
+ Elf_Sym *sym;
+ char *symname;
+ unsigned long sympos;
+
+ relas = (Elf_Rela *) relasec->sh_addr;
+ /* For each rela in this klp relocation section */
+ for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
+ sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info);
+ if (sym->st_shndx != SHN_LIVEPATCH)
+ return -EINVAL;
+
+ klp_clear_buf(&bufs);
+
+ /* Format: .klp.sym.objname.symbol_name,sympos */
+ symname = pmod->core_kallsyms.strtab + sym->st_name;
+ cnt = sscanf(symname, ".klp.sym.%64[^.].%128[^,],%lu",
+ bufs.objname, bufs.symname, &sympos);
Note that MODULE_NAME_LEN even is not 64. It is defined by:
#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
I strongly suggest to use the proposal from Josh.
Hm, looks like my suggestion to use __stringify(MODULE_NAME_LEN) doesn't
work. It results in the string "MODULE_NAME_LEN". Which surprises me:
isn't is supposed to resolve the macro before applying the '#' operation
to it?
Turns out I hadn't included module.h. When I do so,
__stringify(MODULE_NAME_LEN) becomes "(64 - sizeof(unsigned long))".
Which is still not going to work :-/
I was going to suggest another idea: hard-code it at 63 and then do
something like
BUILD_BUG_ON(MODULE_NAME_LEN != 64)
But you're right... it's not even 64!
Need to think on this some more...
On Mon, Mar 21, 2016 at 11:46:51AM -0500, Josh Poimboeuf wrote:
quoted
On Mon, Mar 21, 2016 at 05:31:57PM +0100, Petr Mladek wrote:
quoted
quoted
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.cindex 780f00c..2aa20fa 100644--- a/kernel/livepatch/core.c+++ b/kernel/livepatch/core.c
+static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod)
+{
+ int i, cnt, vmlinux, ret;
+ struct klp_buf bufs = {0};
+ Elf_Rela *relas;
+ Elf_Sym *sym;
+ char *symname;
+ unsigned long sympos;
+
+ relas = (Elf_Rela *) relasec->sh_addr;
+ /* For each rela in this klp relocation section */
+ for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
+ sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info);
+ if (sym->st_shndx != SHN_LIVEPATCH)
+ return -EINVAL;
+
+ klp_clear_buf(&bufs);
+
+ /* Format: .klp.sym.objname.symbol_name,sympos */
+ symname = pmod->core_kallsyms.strtab + sym->st_name;
+ cnt = sscanf(symname, ".klp.sym.%64[^.].%128[^,],%lu",
+ bufs.objname, bufs.symname, &sympos);
Note that MODULE_NAME_LEN even is not 64. It is defined by:
#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
I strongly suggest to use the proposal from Josh.
Hm, looks like my suggestion to use __stringify(MODULE_NAME_LEN) doesn't
work. It results in the string "MODULE_NAME_LEN". Which surprises me:
isn't is supposed to resolve the macro before applying the '#' operation
to it?
Turns out I hadn't included module.h. When I do so,
__stringify(MODULE_NAME_LEN) becomes "(64 - sizeof(unsigned long))".
Which is still not going to work :-/
Hm, we probably won't be able to make use of preprocessor tricks here,
since I don't think the preprocessor can even evaluate that expression
(esp. with that sizeof there). This might mean building the format
string at runtime, which may be more trouble than it's worth...
quoted
I was going to suggest another idea: hard-code it at 63 and then do
something like
BUILD_BUG_ON(MODULE_NAME_LEN != 64)
But you're right... it's not even 64!
Need to think on this some more...
I think it is better to make this KSYM_NAME_LEN. KSYM_SYMBOL_LEN looks
like something different and KSYM_NAME_LEN is 128 which you reference
below.
Ack, I did mean to use KSYM_NAME_LEN, thanks.
quoted
+ char objname[MODULE_NAME_LEN];
+};
[...]
quoted
+static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod)
+{
+ int i, cnt, vmlinux, ret;
+ struct klp_buf bufs = {0};
+ Elf_Rela *relas;
+ Elf_Sym *sym;
+ char *symname;
+ unsigned long sympos;
+
+ relas = (Elf_Rela *) relasec->sh_addr;
+ /* For each rela in this klp relocation section */
+ for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
+ sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info);
+ if (sym->st_shndx != SHN_LIVEPATCH)
+ return -EINVAL;
+
+ klp_clear_buf(&bufs);
+
+ /* Format: .klp.sym.objname.symbol_name,sympos */
+ symname = pmod->core_kallsyms.strtab + sym->st_name;
+ cnt = sscanf(symname, ".klp.sym.%64[^.].%128[^,],%lu",
+ bufs.objname, bufs.symname, &sympos);
It would be really nice to change actual values for their macro
definitions, but this would be a mess which is not worth it. Anyway
shouldn't those width modifiers be %63 and %127 to make a room for \0?
Yes, this is a concern and I'm not sure what the best way to fix it
is. If both MODULE_NAME_LEN and KSYM_NAME_LEN were straight up
constants, then I think Josh's stringify approach would have worked
perfectly. However since MODULE_NAME_LEN translates to an expression
(64 - sizeof(unsigned long)), which the preprocessor cannot evaluate,
we will need another approach. Building the format strings at run time
might be messier than we'd like. Alternatively we could just go the
simple route and simply be a bit more aggressive on the upper bound
for the format width; though the size of long varies on different
architectures, afaik the max size it could ever be on any arch is 8
bytes, so perhaps 64 - 8 = 56 (then - 1 to make room for \0) might be
an appropriate field width. This would deserve a comment as well.
quoted
+ if (cnt != 3)
+ return -EINVAL;
+
+ /* klp_find_object_symbol() treats a NULL objname as vmlinux */
+ vmlinux = !strcmp(bufs.objname, "vmlinux");
+ ret = klp_find_object_symbol(vmlinux ? NULL : bufs.objname,
+ bufs.symname, sympos,
+ (unsigned long *) &sym->st_value);
+ if (ret)
+ return ret;
}
- preempt_enable();
- /*
- * Check if it's in another .o within the patch module. This also
- * checks that the external symbol is unique.
- */
- return klp_find_object_symbol(pmod->name, name, 0, addr);
+ return 0;
}
static int klp_write_object_relocations(struct module *pmod,
struct klp_object *obj)
{
- int ret = 0;
- unsigned long val;
- struct klp_reloc *reloc;
+ int i, cnt, ret = 0;
+ const char *objname, *secname;
+ struct klp_buf bufs = {0};
+ Elf_Shdr *sec;
if (WARN_ON(!klp_is_object_loaded(obj)))
return -EINVAL;
- if (WARN_ON(!obj->relocs))
- return -EINVAL;
+ objname = klp_is_module(obj) ? obj->name : "vmlinux";
module_disable_ro(pmod);
+ /* For each klp relocation section */
+ for (i = 1; i < pmod->klp_info->hdr.e_shnum; i++) {
+ sec = pmod->klp_info->sechdrs + i;
+ if (!(sec->sh_flags & SHF_RELA_LIVEPATCH))
+ continue;
- for (reloc = obj->relocs; reloc->name; reloc++) {
- /* discover the address of the referenced symbol */
- if (reloc->external) {
- if (reloc->sympos > 0) {
- pr_err("non-zero sympos for external reloc symbol '%s' is not supported\n",
- reloc->name);
- ret = -EINVAL;
- goto out;
- }
- ret = klp_find_external_symbol(pmod, reloc->name, &val);
- } else
- ret = klp_find_object_symbol(obj->name,
- reloc->name,
- reloc->sympos,
- &val);
- if (ret)
- goto out;
+ klp_clear_buf(&bufs);
- ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc,
- val + reloc->addend);
- if (ret) {
- pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n",
- reloc->name, val, ret);
- goto out;
+ /* Check if this klp relocation section belongs to obj */
+ secname = pmod->klp_info->secstrings + sec->sh_name;
+ cnt = sscanf(secname, ".klp.rela.%64[^.]", bufs.objname);
Same here.
Otherwise it looks really good (which applies for the whole series), so
after fixing these nits you can add my
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Cheers,
Miroslav
I think it is better to make this KSYM_NAME_LEN. KSYM_SYMBOL_LEN looks
like something different and KSYM_NAME_LEN is 128 which you reference
below.
Ack, I did mean to use KSYM_NAME_LEN, thanks.
quoted
quoted
+ char objname[MODULE_NAME_LEN];
+};
[...]
quoted
+static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod)
+{
+ int i, cnt, vmlinux, ret;
+ struct klp_buf bufs = {0};
+ Elf_Rela *relas;
+ Elf_Sym *sym;
+ char *symname;
+ unsigned long sympos;
+
+ relas = (Elf_Rela *) relasec->sh_addr;
+ /* For each rela in this klp relocation section */
+ for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
+ sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info);
+ if (sym->st_shndx != SHN_LIVEPATCH)
+ return -EINVAL;
+
+ klp_clear_buf(&bufs);
+
+ /* Format: .klp.sym.objname.symbol_name,sympos */
+ symname = pmod->core_kallsyms.strtab + sym->st_name;
+ cnt = sscanf(symname, ".klp.sym.%64[^.].%128[^,],%lu",
+ bufs.objname, bufs.symname, &sympos);
It would be really nice to change actual values for their macro
definitions, but this would be a mess which is not worth it. Anyway
shouldn't those width modifiers be %63 and %127 to make a room for \0?
Yes, this is a concern and I'm not sure what the best way to fix it
is. If both MODULE_NAME_LEN and KSYM_NAME_LEN were straight up
constants, then I think Josh's stringify approach would have worked
perfectly. However since MODULE_NAME_LEN translates to an expression
(64 - sizeof(unsigned long)), which the preprocessor cannot evaluate,
we will need another approach. Building the format strings at run time
might be messier than we'd like. Alternatively we could just go the
simple route and simply be a bit more aggressive on the upper bound
for the format width; though the size of long varies on different
architectures, afaik the max size it could ever be on any arch is 8
bytes, so perhaps 64 - 8 = 56 (then - 1 to make room for \0) might be
an appropriate field width. This would deserve a comment as well.
I think something like that would be good, along with:
BUILD_BUG_ON(MODULE_NAME_LEN < 56);
and a comment explaining why.
--
Josh
Yes, this is a concern and I'm not sure what the best way to fix it
is. If both MODULE_NAME_LEN and KSYM_NAME_LEN were straight up
constants, then I think Josh's stringify approach would have worked
perfectly. However since MODULE_NAME_LEN translates to an expression
(64 - sizeof(unsigned long)), which the preprocessor cannot evaluate,
we will need another approach. Building the format strings at run time
might be messier than we'd like. Alternatively we could just go the
simple route and simply be a bit more aggressive on the upper bound
for the format width; though the size of long varies on different
architectures, afaik the max size it could ever be on any arch is 8
bytes, so perhaps 64 - 8 = 56 (then - 1 to make room for \0) might be
an appropriate field width. This would deserve a comment as well.
So how about actually modifying MAX_PARAM_PREFIX_LEN so
that it's actually properly evaluable at preprocessing time,
i.e. something along the lines of
@@ -14,7 +14,7 @@#endif/* Chosen so that structs with an unsigned long line up. */-#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))+#define MAX_PARAM_PREFIX_LEN (64 - __SIZEOF_LONG__)#ifdef MODULE#define __MODULE_INFO(tag, name, info) \
On Mon, Mar 21, 2016 at 10:16:17PM +0100, Jiri Kosina wrote:
quoted hunk
On Mon, 21 Mar 2016, Jessica Yu wrote:
quoted
Yes, this is a concern and I'm not sure what the best way to fix it
is. If both MODULE_NAME_LEN and KSYM_NAME_LEN were straight up
constants, then I think Josh's stringify approach would have worked
perfectly. However since MODULE_NAME_LEN translates to an expression
(64 - sizeof(unsigned long)), which the preprocessor cannot evaluate,
we will need another approach. Building the format strings at run time
might be messier than we'd like. Alternatively we could just go the
simple route and simply be a bit more aggressive on the upper bound
for the format width; though the size of long varies on different
architectures, afaik the max size it could ever be on any arch is 8
bytes, so perhaps 64 - 8 = 56 (then - 1 to make room for \0) might be
an appropriate field width. This would deserve a comment as well.
So how about actually modifying MAX_PARAM_PREFIX_LEN so
that it's actually properly evaluable at preprocessing time,
i.e. something along the lines of
@@ -14,7 +14,7 @@#endif/* Chosen so that structs with an unsigned long line up. */-#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))+#define MAX_PARAM_PREFIX_LEN (64 - __SIZEOF_LONG__)#ifdef MODULE#define __MODULE_INFO(tag, name, info) \
According to my test that still results in the literal value of
"(64 - 8)".
--
Josh
According to my test that still results in the literal value of
"(64 - 8)".
Alright. But we should be able to special-case it with a two #if checks on
the __SIZEOF_LONG__ value and BUILD_BUG_ON() when __SIZEOF_LONG__ is not
of one of the ususal sizes.
Thanks,
--
Jiri Kosina
SUSE Labs
On Wed, Mar 16, 2016 at 03:47:04PM -0400, Jessica Yu wrote:
quoted
For livepatch modules, copy Elf section, symbol, and string information
from the load_info struct in the module loader. Persist copies of the
original symbol table and string table.
Livepatch manages its own relocation sections in order to reuse module
loader code to write relocations. Livepatch modules must preserve Elf
information such as section indices in order to apply livepatch relocation
sections using the module loader's apply_relocate_add() function.
In order to apply livepatch relocation sections, livepatch modules must
keep a complete copy of their original symbol table in memory. Normally, a
stripped down copy of a module's symbol table (containing only "core"
symbols) is made available through module->core_symtab. But for livepatch
modules, the symbol table copied into memory on module load must be exactly
the same as the symbol table produced when the patch module was compiled.
This is because the relocations in each livepatch relocation section refer
to their respective symbols with their symbol indices, and the original
symbol indices (and thus the symtab ordering) must be preserved in order
for apply_relocate_add() to find the right symbol.
Signed-off-by: Jessica Yu <redacted>
---
include/linux/module.h | 25 ++++++++++
kernel/module.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 146 insertions(+), 2 deletions(-)
@@ -456,7 +465,11 @@ struct module {#endif#ifdef CONFIG_LIVEPATCH+boolklp;/* Is this a livepatch module? */boolklp_alive;++/* Elf information */+structklp_modinfo*klp_info;#endif#ifdef CONFIG_MODULE_UNLOAD
@@ -630,6 +643,18 @@ static inline bool module_requested_async_probing(struct module *module)returnmodule&&module->async_probe_requested;}+#ifdef CONFIG_LIVEPATCH+staticinlineboolis_livepatch_module(structmodule*mod)+{+returnmod->klp;+}+#else /* !CONFIG_LIVEPATCH */+staticinlineboolis_livepatch_module(structmodule*mod)+{+returnfalse;+}+#endif /* CONFIG_LIVEPATCH */+#else /* !CONFIG_MODULES... *//* Given an address, look for it in the exception tables. */
On Tue, Mar 22, 2016 at 01:57:01PM -0400, Jessica Yu wrote:
quoted hunk
+++ Josh Poimboeuf [21/03/16 09:06 -0500]:
quoted
On Wed, Mar 16, 2016 at 03:47:04PM -0400, Jessica Yu wrote:
quoted
For livepatch modules, copy Elf section, symbol, and string information
from the load_info struct in the module loader. Persist copies of the
original symbol table and string table.
Livepatch manages its own relocation sections in order to reuse module
loader code to write relocations. Livepatch modules must preserve Elf
information such as section indices in order to apply livepatch relocation
sections using the module loader's apply_relocate_add() function.
In order to apply livepatch relocation sections, livepatch modules must
keep a complete copy of their original symbol table in memory. Normally, a
stripped down copy of a module's symbol table (containing only "core"
symbols) is made available through module->core_symtab. But for livepatch
modules, the symbol table copied into memory on module load must be exactly
the same as the symbol table produced when the patch module was compiled.
This is because the relocations in each livepatch relocation section refer
to their respective symbols with their symbol indices, and the original
symbol indices (and thus the symtab ordering) must be preserved in order
for apply_relocate_add() to find the right symbol.
Signed-off-by: Jessica Yu <redacted>
---
include/linux/module.h | 25 ++++++++++
kernel/module.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 146 insertions(+), 2 deletions(-)
Oops, sorry, I missed that line! It would be good to wrap it like:
mod->klp_info->sechdrs[symndx].sh_addr = \
(unsigned long) mod->core_kallsyms.symtab;
--
Josh
According to my test that still results in the literal value of
"(64 - 8)".
Alright. But we should be able to special-case it with a two #if checks on
the __SIZEOF_LONG__ value and BUILD_BUG_ON() when __SIZEOF_LONG__ is not
of one of the ususal sizes.
And while we're at it, we might as well add a BUILD_BUG_ON check for
KSYM_NAME_LEN too, since we are also hard coding that field width, and
we'd like to be alerted if that value ever changes.