Skip to content

Commit

Permalink
modpost: Add modinfo flag to livepatch modules
Browse files Browse the repository at this point in the history
Currently, livepatch infrastructure in the kernel relies on
MODULE_INFO(livepatch, "Y") statement in a livepatch module. Then the
kernel module loader knows a module is indeed livepatch module and can
behave accordingly.

klp-convert, on the other hand relies on LIVEPATCH_* statement in the
module's Makefile for exactly the same reason.

Remove dependency on modinfo and generate MODULE_INFO flag
automatically in modpost when LIVEPATCH_* is defined in the module's
Makefile. Generate a list of all built livepatch modules based on
the .livepatch file and store it in (MODVERDIR)/livepatchmods. Give
this list as an argument for modpost which will use it to identify
livepatch modules.

As MODULE_INFO is no longer needed, remove it.

[jmoreira:
* fix modpost.c (add_livepatch_flag) to update module structure with
livepatch flag and prevent modpost from breaking due to unresolved
symbols]

[joe:
* adjust modpost.c::get_modinfo() call for v5.0 version]

Signed-off-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Joao Moreira <jmoreira@suse.de>
  • Loading branch information
mirab authored and joe-lawrence committed Mar 18, 2019
1 parent 543aa6b commit 4a61628
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 8 deletions.
1 change: 0 additions & 1 deletion samples/livepatch/livepatch-sample.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,3 @@ static void livepatch_exit(void)
module_init(livepatch_init);
module_exit(livepatch_exit);
MODULE_LICENSE("GPL");
MODULE_INFO(livepatch, "Y");
8 changes: 7 additions & 1 deletion scripts/Makefile.modpost
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ MODLISTCMD := find $(MODVERDIR) -name '*.mod' | xargs -r grep -h '\.ko$$' | sort
__modules := $(shell $(MODLISTCMD))
modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))

# find all .livepatch files listed in $(MODVERDIR)/
ifdef CONFIG_LIVEPATCH
$(shell find $(MODVERDIR) -name '*.livepatch' | xargs -r -I{} basename {} .livepatch > $(MODVERDIR)/livepatchmods)
endif

# Stop after building .o files if NOFINAL is set. Makes compile tests quicker
_modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules))

Expand All @@ -79,7 +84,8 @@ modpost = scripts/mod/modpost \
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
$(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
$(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
$(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
$(if $(CONFIG_LIVEPATCH),-l $(MODVERDIR)/livepatchmods)

MODPOST_OPT=$(subst -i,-n,$(filter -i,$(MAKEFLAGS)))

Expand Down
84 changes: 78 additions & 6 deletions scripts/mod/modpost.c
Original file line number Diff line number Diff line change
Expand Up @@ -1979,10 +1979,6 @@ static void read_symbols(const char *modname)
license = get_next_modinfo(&info, "license", license);
}

/* Livepatch modules have unresolved symbols resolved by klp-convert */
if (get_modinfo(&info, "livepatch"))
mod->livepatch = 1;

for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
symname = remove_dot(info.strtab + sym->st_name);

Expand Down Expand Up @@ -2421,6 +2417,76 @@ static void write_dump(const char *fname)
free(buf.p);
}

struct livepatch_mod_list {
struct livepatch_mod_list *next;
char *livepatch_mod;
};

static struct livepatch_mod_list *load_livepatch_mods(const char *fname)
{
struct livepatch_mod_list *list_iter, *list_start = NULL;
unsigned long size, pos = 0;
void *file = grab_file(fname, &size);
char *line;

if (!file)
return NULL;

while ((line = get_next_line(&pos, file, size))) {
list_iter = NOFAIL(malloc(sizeof(*list_iter)));
list_iter->next = list_start;
list_iter->livepatch_mod = NOFAIL(strdup(line));
list_start = list_iter;
}
release_file(file, size);

return list_start;
}

static void free_livepatch_mods(struct livepatch_mod_list *list_start)
{
struct livepatch_mod_list *list_iter;

while (list_start) {
list_iter = list_start->next;
free(list_start->livepatch_mod);
free(list_start);
list_start = list_iter;
}
}

static int is_livepatch_mod(const char *modname,
struct livepatch_mod_list *list)
{
const char *myname;

if (!list)
return 0;

myname = strrchr(modname, '/');
if (myname)
myname++;
else
myname = modname;

while (list) {
if (!strcmp(myname, list->livepatch_mod))
return 1;
list = list->next;
}
return 0;
}

static void add_livepatch_flag(struct buffer *b, struct module *mod,
struct livepatch_mod_list *list)
{
if (is_livepatch_mod(mod->name, list)) {
buf_printf(b, "\nMODULE_INFO(livepatch, \"Y\");\n");
mod->livepatch = 1;
}
}


struct ext_sym_list {
struct ext_sym_list *next;
const char *file;
Expand All @@ -2436,8 +2502,9 @@ int main(int argc, char **argv)
int err;
struct ext_sym_list *extsym_iter;
struct ext_sym_list *extsym_start = NULL;
struct livepatch_mod_list *livepatch_mods = NULL;

while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awE")) != -1) {
while ((opt = getopt(argc, argv, "i:I:e:l:mnsST:o:awM:K:E")) != -1) {
switch (opt) {
case 'i':
kernel_read = optarg;
Expand All @@ -2454,6 +2521,9 @@ int main(int argc, char **argv)
extsym_iter->file = optarg;
extsym_start = extsym_iter;
break;
case 'l':
livepatch_mods = load_livepatch_mods(optarg);
break;
case 'm':
modversions = 1;
break;
Expand Down Expand Up @@ -2514,15 +2584,16 @@ int main(int argc, char **argv)
buf.pos = 0;

err |= check_modname_len(mod);
err |= check_exports(mod);
add_header(&buf, mod);
add_intree_flag(&buf, !external_module);
add_retpoline(&buf);
add_staging_flag(&buf, mod->name);
add_livepatch_flag(&buf, mod, livepatch_mods);
err |= add_versions(&buf, mod);
add_depends(&buf, mod);
add_moddevtable(&buf, mod);
add_srcversion(&buf, mod);
err |= check_exports(mod);

sprintf(fname, "%s.mod.c", mod->name);
write_if_changed(&buf, fname);
Expand All @@ -2541,6 +2612,7 @@ int main(int argc, char **argv)
"Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
}
}
free_livepatch_mods(livepatch_mods);
free(buf.p);

return err;
Expand Down

0 comments on commit 4a61628

Please sign in to comment.