Skip to content

Commit ca376a9

Browse files
jpoimboeJiri Kosina
authored andcommitted
livepatch: Prevent module-specific KLP rela sections from referencing vmlinux symbols
Prevent module-specific KLP rela sections from referencing vmlinux symbols. This helps prevent ordering issues with module special section initializations. Presumably such symbols are exported and normal relas can be used instead. Suggested-by: Peter Zijlstra <[email protected]> Signed-off-by: Josh Poimboeuf <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Joe Lawrence <[email protected]> Acked-by: Miroslav Benes <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 1d05334 commit ca376a9

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

kernel/livepatch/core.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -192,17 +192,20 @@ static int klp_find_object_symbol(const char *objname, const char *name,
192192
}
193193

194194
static int klp_resolve_symbols(Elf64_Shdr *sechdrs, const char *strtab,
195-
unsigned int symndx, Elf_Shdr *relasec)
195+
unsigned int symndx, Elf_Shdr *relasec,
196+
const char *sec_objname)
196197
{
197-
int i, cnt, vmlinux, ret;
198-
char objname[MODULE_NAME_LEN];
199-
char symname[KSYM_NAME_LEN];
198+
int i, cnt, ret;
199+
char sym_objname[MODULE_NAME_LEN];
200+
char sym_name[KSYM_NAME_LEN];
200201
Elf_Rela *relas;
201202
Elf_Sym *sym;
202203
unsigned long sympos, addr;
204+
bool sym_vmlinux;
205+
bool sec_vmlinux = !strcmp(sec_objname, "vmlinux");
203206

204207
/*
205-
* Since the field widths for objname and symname in the sscanf()
208+
* Since the field widths for sym_objname and sym_name in the sscanf()
206209
* call are hard-coded and correspond to MODULE_NAME_LEN and
207210
* KSYM_NAME_LEN respectively, we must make sure that MODULE_NAME_LEN
208211
* and KSYM_NAME_LEN have the values we expect them to have.
@@ -223,20 +226,33 @@ static int klp_resolve_symbols(Elf64_Shdr *sechdrs, const char *strtab,
223226
return -EINVAL;
224227
}
225228

226-
/* Format: .klp.sym.objname.symname,sympos */
229+
/* Format: .klp.sym.sym_objname.sym_name,sympos */
227230
cnt = sscanf(strtab + sym->st_name,
228231
".klp.sym.%55[^.].%127[^,],%lu",
229-
objname, symname, &sympos);
232+
sym_objname, sym_name, &sympos);
230233
if (cnt != 3) {
231234
pr_err("symbol %s has an incorrectly formatted name\n",
232235
strtab + sym->st_name);
233236
return -EINVAL;
234237
}
235238

239+
sym_vmlinux = !strcmp(sym_objname, "vmlinux");
240+
241+
/*
242+
* Prevent module-specific KLP rela sections from referencing
243+
* vmlinux symbols. This helps prevent ordering issues with
244+
* module special section initializations. Presumably such
245+
* symbols are exported and normal relas can be used instead.
246+
*/
247+
if (!sec_vmlinux && sym_vmlinux) {
248+
pr_err("invalid access to vmlinux symbol '%s' from module-specific livepatch relocation section",
249+
sym_name);
250+
return -EINVAL;
251+
}
252+
236253
/* klp_find_object_symbol() treats a NULL objname as vmlinux */
237-
vmlinux = !strcmp(objname, "vmlinux");
238-
ret = klp_find_object_symbol(vmlinux ? NULL : objname,
239-
symname, sympos, &addr);
254+
ret = klp_find_object_symbol(sym_vmlinux ? NULL : sym_objname,
255+
sym_name, sympos, &addr);
240256
if (ret)
241257
return ret;
242258

@@ -294,7 +310,7 @@ int klp_apply_section_relocs(struct module *pmod, Elf_Shdr *sechdrs,
294310
if (strcmp(objname ? objname : "vmlinux", sec_objname))
295311
return 0;
296312

297-
ret = klp_resolve_symbols(sechdrs, strtab, symndx, sec);
313+
ret = klp_resolve_symbols(sechdrs, strtab, symndx, sec, sec_objname);
298314
if (ret)
299315
return ret;
300316

0 commit comments

Comments
 (0)