Skip to content

Commit 0f0836b

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching
Pull livepatching updates from Jiri Kosina: - RO/NX attribute fixes for patch module relocations from Josh Poimboeuf. As part of this effort, module.c has been cleaned up as well and livepatching is piggy-backing on this cleanup. Rusty is OK with this whole lot going through livepatching tree. - symbol disambiguation support from Chris J Arges. That series is also Reviewed-by: Miroslav Benes <mbenes@suse.cz> but this came in only after I've alredy pushed out. Didn't want to rebase because of that, hence I am mentioning it here. - symbol lookup fix from Miroslav Benes * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching: livepatch: Cleanup module page permission changes module: keep percpu symbols in module's symtab module: clean up RO/NX handling. module: use a structure to encapsulate layout. gcov: use within_module() helper. module: Use the same logic for setting and unsetting RO/NX livepatch: function,sympos scheme in livepatch sysfs directory livepatch: add sympos as disambiguator field to klp_reloc livepatch: add old_sympos as disambiguator field to klp_func
2 parents c2848f2 + b56b36e commit 0f0836b

File tree

18 files changed

+340
-427
lines changed

18 files changed

+340
-427
lines changed

Documentation/ABI/testing/sysfs-kernel-livepatch

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@ Description:
3333
The object directory contains subdirectories for each function
3434
that is patched within the object.
3535

36-
What: /sys/kernel/livepatch/<patch>/<object>/<function>
36+
What: /sys/kernel/livepatch/<patch>/<object>/<function,sympos>
3737
Date: Nov 2014
3838
KernelVersion: 3.19.0
3939
Contact: live-patching@vger.kernel.org
4040
Description:
4141
The function directory contains attributes regarding the
4242
properties and state of the patched function.
4343

44+
The directory name contains the patched function name and a
45+
sympos number corresponding to the nth occurrence of the symbol
46+
name in kallsyms for the patched object.
47+
4448
There are currently no such attributes.

arch/alpha/kernel/module.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
160160

161161
/* The small sections were sorted to the end of the segment.
162162
The following should definitely cover them. */
163-
gp = (u64)me->module_core + me->core_size - 0x8000;
163+
gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000;
164164
got = sechdrs[me->arch.gotsecindex].sh_addr;
165165

166166
for (i = 0; i < n; i++) {

arch/arc/kernel/unwind.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,8 @@ void *unwind_add_table(struct module *module, const void *table_start,
385385
return NULL;
386386

387387
init_unwind_table(table, module->name,
388-
module->module_core, module->core_size,
389-
module->module_init, module->init_size,
388+
module->core_layout.base, module->core_layout.size,
389+
module->init_layout.base, module->init_layout.size,
390390
table_start, table_size,
391391
NULL, 0);
392392

arch/arm/kernel/module-plts.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct plt_entries {
3232

3333
static bool in_init(const struct module *mod, u32 addr)
3434
{
35-
return addr - (u32)mod->module_init < mod->init_size;
35+
return addr - (u32)mod->init_layout.base < mod->init_layout.size;
3636
}
3737

3838
u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)

arch/avr32/kernel/module.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
118118
* Increase core size to make room for GOT and set start
119119
* offset for GOT.
120120
*/
121-
module->core_size = ALIGN(module->core_size, 4);
122-
module->arch.got_offset = module->core_size;
123-
module->core_size += module->arch.got_size;
121+
module->core_layout.size = ALIGN(module->core_layout.size, 4);
122+
module->arch.got_offset = module->core_layout.size;
123+
module->core_layout.size += module->arch.got_size;
124124

125125
return 0;
126126

@@ -177,7 +177,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
177177
if (!info->got_initialized) {
178178
Elf32_Addr *gotent;
179179

180-
gotent = (module->module_core
180+
gotent = (module->core_layout.base
181181
+ module->arch.got_offset
182182
+ info->got_offset);
183183
*gotent = relocation;
@@ -255,8 +255,8 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
255255
*/
256256
pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n",
257257
relocation, module->arch.got_offset,
258-
module->module_core);
259-
relocation -= ((unsigned long)module->module_core
258+
module->core_layout.base);
259+
relocation -= ((unsigned long)module->core_layout.base
260260
+ module->arch.got_offset);
261261
*location = relocation;
262262
break;

arch/ia64/kernel/module.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -486,13 +486,13 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
486486
static inline int
487487
in_init (const struct module *mod, uint64_t addr)
488488
{
489-
return addr - (uint64_t) mod->module_init < mod->init_size;
489+
return addr - (uint64_t) mod->init_layout.base < mod->init_layout.size;
490490
}
491491

492492
static inline int
493493
in_core (const struct module *mod, uint64_t addr)
494494
{
495-
return addr - (uint64_t) mod->module_core < mod->core_size;
495+
return addr - (uint64_t) mod->core_layout.base < mod->core_layout.size;
496496
}
497497

498498
static inline int
@@ -675,7 +675,7 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
675675
break;
676676

677677
case RV_BDREL:
678-
val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
678+
val -= (uint64_t) (in_init(mod, val) ? mod->init_layout.base : mod->core_layout.base);
679679
break;
680680

681681
case RV_LTV:
@@ -810,15 +810,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
810810
* addresses have been selected...
811811
*/
812812
uint64_t gp;
813-
if (mod->core_size > MAX_LTOFF)
813+
if (mod->core_layout.size > MAX_LTOFF)
814814
/*
815815
* This takes advantage of fact that SHF_ARCH_SMALL gets allocated
816816
* at the end of the module.
817817
*/
818-
gp = mod->core_size - MAX_LTOFF / 2;
818+
gp = mod->core_layout.size - MAX_LTOFF / 2;
819819
else
820-
gp = mod->core_size / 2;
821-
gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
820+
gp = mod->core_layout.size / 2;
821+
gp = (uint64_t) mod->core_layout.base + ((gp + 7) & -8);
822822
mod->arch.gp = gp;
823823
DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
824824
}

arch/metag/kernel/module.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ static uint32_t do_plt_call(void *location, Elf32_Addr val,
176176
tramp[1] = 0xac000001 | ((val & 0x0000ffff) << 3);
177177

178178
/* Init, or core PLT? */
179-
if (location >= mod->module_core
180-
&& location < mod->module_core + mod->core_size)
179+
if (location >= mod->core_layout.base
180+
&& location < mod->core_layout.base + mod->core_layout.size)
181181
entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
182182
else
183183
entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;

arch/mips/kernel/vpe.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,11 @@ static void layout_sections(struct module *mod, const Elf_Ehdr *hdr,
205205
|| s->sh_entsize != ~0UL)
206206
continue;
207207
s->sh_entsize =
208-
get_offset((unsigned long *)&mod->core_size, s);
208+
get_offset((unsigned long *)&mod->core_layout.size, s);
209209
}
210210

211211
if (m == 0)
212-
mod->core_text_size = mod->core_size;
212+
mod->core_layout.text_size = mod->core_layout.size;
213213

214214
}
215215
}
@@ -641,7 +641,7 @@ static int vpe_elfload(struct vpe *v)
641641
layout_sections(&mod, hdr, sechdrs, secstrings);
642642
}
643643

644-
v->load_addr = alloc_progmem(mod.core_size);
644+
v->load_addr = alloc_progmem(mod.core_layout.size);
645645
if (!v->load_addr)
646646
return -ENOMEM;
647647

arch/parisc/kernel/module.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@
4242
* We are not doing SEGREL32 handling correctly. According to the ABI, we
4343
* should do a value offset, like this:
4444
* if (in_init(me, (void *)val))
45-
* val -= (uint32_t)me->module_init;
45+
* val -= (uint32_t)me->init_layout.base;
4646
* else
47-
* val -= (uint32_t)me->module_core;
47+
* val -= (uint32_t)me->core_layout.base;
4848
* However, SEGREL32 is used only for PARISC unwind entries, and we want
4949
* those entries to have an absolute address, and not just an offset.
5050
*
@@ -100,14 +100,14 @@
100100
* or init pieces the location is */
101101
static inline int in_init(struct module *me, void *loc)
102102
{
103-
return (loc >= me->module_init &&
104-
loc <= (me->module_init + me->init_size));
103+
return (loc >= me->init_layout.base &&
104+
loc <= (me->init_layout.base + me->init_layout.size));
105105
}
106106

107107
static inline int in_core(struct module *me, void *loc)
108108
{
109-
return (loc >= me->module_core &&
110-
loc <= (me->module_core + me->core_size));
109+
return (loc >= me->core_layout.base &&
110+
loc <= (me->core_layout.base + me->core_layout.size));
111111
}
112112

113113
static inline int in_local(struct module *me, void *loc)
@@ -367,13 +367,13 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
367367
}
368368

369369
/* align things a bit */
370-
me->core_size = ALIGN(me->core_size, 16);
371-
me->arch.got_offset = me->core_size;
372-
me->core_size += gots * sizeof(struct got_entry);
370+
me->core_layout.size = ALIGN(me->core_layout.size, 16);
371+
me->arch.got_offset = me->core_layout.size;
372+
me->core_layout.size += gots * sizeof(struct got_entry);
373373

374-
me->core_size = ALIGN(me->core_size, 16);
375-
me->arch.fdesc_offset = me->core_size;
376-
me->core_size += fdescs * sizeof(Elf_Fdesc);
374+
me->core_layout.size = ALIGN(me->core_layout.size, 16);
375+
me->arch.fdesc_offset = me->core_layout.size;
376+
me->core_layout.size += fdescs * sizeof(Elf_Fdesc);
377377

378378
me->arch.got_max = gots;
379379
me->arch.fdesc_max = fdescs;
@@ -391,7 +391,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
391391

392392
BUG_ON(value == 0);
393393

394-
got = me->module_core + me->arch.got_offset;
394+
got = me->core_layout.base + me->arch.got_offset;
395395
for (i = 0; got[i].addr; i++)
396396
if (got[i].addr == value)
397397
goto out;
@@ -409,7 +409,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
409409
#ifdef CONFIG_64BIT
410410
static Elf_Addr get_fdesc(struct module *me, unsigned long value)
411411
{
412-
Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
412+
Elf_Fdesc *fdesc = me->core_layout.base + me->arch.fdesc_offset;
413413

414414
if (!value) {
415415
printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
@@ -427,7 +427,7 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
427427

428428
/* Create new one */
429429
fdesc->addr = value;
430-
fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
430+
fdesc->gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
431431
return (Elf_Addr)fdesc;
432432
}
433433
#endif /* CONFIG_64BIT */
@@ -839,7 +839,7 @@ register_unwind_table(struct module *me,
839839

840840
table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
841841
end = table + sechdrs[me->arch.unwind_section].sh_size;
842-
gp = (Elf_Addr)me->module_core + me->arch.got_offset;
842+
gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
843843

844844
DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
845845
me->arch.unwind_section, table, end, gp);

arch/powerpc/kernel/module_32.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ static uint32_t do_plt_call(void *location,
188188

189189
pr_debug("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
190190
/* Init, or core PLT? */
191-
if (location >= mod->module_core
192-
&& location < mod->module_core + mod->core_size)
191+
if (location >= mod->core_layout.base
192+
&& location < mod->core_layout.base + mod->core_layout.size)
193193
entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
194194
else
195195
entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
@@ -296,7 +296,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
296296
}
297297
#ifdef CONFIG_DYNAMIC_FTRACE
298298
module->arch.tramp =
299-
do_plt_call(module->module_core,
299+
do_plt_call(module->core_layout.base,
300300
(unsigned long)ftrace_caller,
301301
sechdrs, module);
302302
#endif

arch/s390/kernel/module.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,11 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
159159

160160
/* Increase core size by size of got & plt and set start
161161
offsets for got and plt. */
162-
me->core_size = ALIGN(me->core_size, 4);
163-
me->arch.got_offset = me->core_size;
164-
me->core_size += me->arch.got_size;
165-
me->arch.plt_offset = me->core_size;
166-
me->core_size += me->arch.plt_size;
162+
me->core_layout.size = ALIGN(me->core_layout.size, 4);
163+
me->arch.got_offset = me->core_layout.size;
164+
me->core_layout.size += me->arch.got_size;
165+
me->arch.plt_offset = me->core_layout.size;
166+
me->core_layout.size += me->arch.plt_size;
167167
return 0;
168168
}
169169

@@ -279,7 +279,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
279279
if (info->got_initialized == 0) {
280280
Elf_Addr *gotent;
281281

282-
gotent = me->module_core + me->arch.got_offset +
282+
gotent = me->core_layout.base + me->arch.got_offset +
283283
info->got_offset;
284284
*gotent = val;
285285
info->got_initialized = 1;
@@ -302,7 +302,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
302302
rc = apply_rela_bits(loc, val, 0, 64, 0);
303303
else if (r_type == R_390_GOTENT ||
304304
r_type == R_390_GOTPLTENT) {
305-
val += (Elf_Addr) me->module_core - loc;
305+
val += (Elf_Addr) me->core_layout.base - loc;
306306
rc = apply_rela_bits(loc, val, 1, 32, 1);
307307
}
308308
break;
@@ -315,7 +315,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
315315
case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
316316
if (info->plt_initialized == 0) {
317317
unsigned int *ip;
318-
ip = me->module_core + me->arch.plt_offset +
318+
ip = me->core_layout.base + me->arch.plt_offset +
319319
info->plt_offset;
320320
ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
321321
ip[1] = 0x100a0004;
@@ -334,7 +334,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
334334
val - loc + 0xffffUL < 0x1ffffeUL) ||
335335
(r_type == R_390_PLT32DBL &&
336336
val - loc + 0xffffffffULL < 0x1fffffffeULL)))
337-
val = (Elf_Addr) me->module_core +
337+
val = (Elf_Addr) me->core_layout.base +
338338
me->arch.plt_offset +
339339
info->plt_offset;
340340
val += rela->r_addend - loc;
@@ -356,7 +356,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
356356
case R_390_GOTOFF32: /* 32 bit offset to GOT. */
357357
case R_390_GOTOFF64: /* 64 bit offset to GOT. */
358358
val = val + rela->r_addend -
359-
((Elf_Addr) me->module_core + me->arch.got_offset);
359+
((Elf_Addr) me->core_layout.base + me->arch.got_offset);
360360
if (r_type == R_390_GOTOFF16)
361361
rc = apply_rela_bits(loc, val, 0, 16, 0);
362362
else if (r_type == R_390_GOTOFF32)
@@ -366,7 +366,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
366366
break;
367367
case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
368368
case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
369-
val = (Elf_Addr) me->module_core + me->arch.got_offset +
369+
val = (Elf_Addr) me->core_layout.base + me->arch.got_offset +
370370
rela->r_addend - loc;
371371
if (r_type == R_390_GOTPC)
372372
rc = apply_rela_bits(loc, val, 1, 32, 0);

arch/x86/kernel/livepatch.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020

2121
#include <linux/module.h>
2222
#include <linux/uaccess.h>
23-
#include <asm/cacheflush.h>
24-
#include <asm/page_types.h>
2523
#include <asm/elf.h>
2624
#include <asm/livepatch.h>
2725

@@ -38,11 +36,10 @@
3836
int klp_write_module_reloc(struct module *mod, unsigned long type,
3937
unsigned long loc, unsigned long value)
4038
{
41-
int ret, numpages, size = 4;
42-
bool readonly;
39+
size_t size = 4;
4340
unsigned long val;
44-
unsigned long core = (unsigned long)mod->module_core;
45-
unsigned long core_size = mod->core_size;
41+
unsigned long core = (unsigned long)mod->core_layout.base;
42+
unsigned long core_size = mod->core_layout.size;
4643

4744
switch (type) {
4845
case R_X86_64_NONE:
@@ -69,23 +66,5 @@ int klp_write_module_reloc(struct module *mod, unsigned long type,
6966
/* loc does not point to any symbol inside the module */
7067
return -EINVAL;
7168

72-
readonly = false;
73-
74-
#ifdef CONFIG_DEBUG_SET_MODULE_RONX
75-
if (loc < core + mod->core_ro_size)
76-
readonly = true;
77-
#endif
78-
79-
/* determine if the relocation spans a page boundary */
80-
numpages = ((loc & PAGE_MASK) == ((loc + size) & PAGE_MASK)) ? 1 : 2;
81-
82-
if (readonly)
83-
set_memory_rw(loc & PAGE_MASK, numpages);
84-
85-
ret = probe_kernel_write((void *)loc, &val, size);
86-
87-
if (readonly)
88-
set_memory_ro(loc & PAGE_MASK, numpages);
89-
90-
return ret;
69+
return probe_kernel_write((void *)loc, &val, size);
9170
}

0 commit comments

Comments
 (0)