Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1326772 > unrolled thread
| Started by | Paul Burton <paul.burton@imgtec.com> |
|---|---|
| First post | 2016-02-04 14:10 +0100 |
| Last post | 2016-02-04 14:10 +0100 |
| Articles | 4 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH v2 0/4] Support new MIPSr6 relocations Paul Burton <paul.burton@imgtec.com> - 2016-02-04 14:10 +0100
[PATCH v2 1/4] MIPS: Bail on unsupported module relocs Paul Burton <paul.burton@imgtec.com> - 2016-02-04 14:10 +0100
[PATCH v2 4/4] MIPS: Support R_MIPS_PC{16,21,26} rel-style relocs Paul Burton <paul.burton@imgtec.com> - 2016-02-04 14:10 +0100
[PATCH v2 2/4] MIPS: module: Make consistent use of pr_*() Paul Burton <paul.burton@imgtec.com> - 2016-02-04 14:10 +0100
| From | Paul Burton <paul.burton@imgtec.com> |
|---|---|
| Date | 2016-02-04 14:10 +0100 |
| Subject | [PATCH v2 0/4] Support new MIPSr6 relocations |
| Message-ID | <qYrPA-Co-9@gated-at.bofh.it> |
MIPSr6 introduced a few new relocations that may be present in loadable
kernel modules. This series introduces support for them in both their
rel & rela forms for MIPS32 & MIPS64 kernels respectively, and ensures
that any future missing relocs cause module loading to fail gracefully.
Paul Burton (3):
MIPS: Bail on unsupported module relocs
MIPS: Support R_MIPS_PC{21,26} rela-style relocs
MIPS: Support R_MIPS_PC{16,21,26} rel-style relocs
Steven J. Hill (1):
MIPS: module: Make consistent use of pr_*()
arch/mips/include/asm/elf.h | 5 +++
arch/mips/kernel/module-rela.c | 75 +++++++++++++++++++++++++++++++++++-----
arch/mips/kernel/module.c | 77 +++++++++++++++++++++++++++++++++++++-----
3 files changed, 140 insertions(+), 17 deletions(-)
--
2.7.0
[toc] | [next] | [standalone]
| From | Paul Burton <paul.burton@imgtec.com> |
|---|---|
| Date | 2016-02-04 14:10 +0100 |
| Subject | [PATCH v2 1/4] MIPS: Bail on unsupported module relocs |
| Message-ID | <qYrPB-Co-37@gated-at.bofh.it> |
| In reply to | #1326772 |
When an unsupported reloc is encountered in a module, we currently
blindly branch to whatever would be at its entry in the reloc handler
function pointer arrays. This may be NULL, or if the unsupported reloc
has a type greater than that of the supported reloc with the highest
type then we'll dereference some value after the function pointer array
& branch to that. The result is at best a kernel oops.
Fix this by checking that the reloc type has an entry in the function
pointer array (ie. is less than the number of items in the array) and
that the handler is non-NULL, returning an error code to fail the module
load if no handler is found.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: James Hogan <james.hogan@imgtec.com>
---
Changes in v2:
- Use pr_err instead of pr_warn.
arch/mips/kernel/module-rela.c | 19 ++++++++++++++++---
arch/mips/kernel/module.c | 19 ++++++++++++++++---
2 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/arch/mips/kernel/module-rela.c b/arch/mips/kernel/module-rela.c
index 2b70723..9083d63 100644
--- a/arch/mips/kernel/module-rela.c
+++ b/arch/mips/kernel/module-rela.c
@@ -109,9 +109,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
struct module *me)
{
Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
+ int (*handler)(struct module *me, u32 *location, Elf_Addr v);
Elf_Sym *sym;
u32 *location;
- unsigned int i;
+ unsigned int i, type;
Elf_Addr v;
int res;
@@ -134,9 +135,21 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
return -ENOENT;
}
- v = sym->st_value + rel[i].r_addend;
+ type = ELF_MIPS_R_TYPE(rel[i]);
+
+ if (type < ARRAY_SIZE(reloc_handlers_rela))
+ handler = reloc_handlers_rela[type];
+ else
+ handler = NULL;
- res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
+ if (!handler) {
+ pr_err("%s: Unknown relocation type %u\n",
+ me->name, type);
+ return -EINVAL;
+ }
+
+ v = sym->st_value + rel[i].r_addend;
+ res = handler(me, location, v);
if (res)
return res;
}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index 1833f51..f9b2936 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -197,9 +197,10 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
struct module *me)
{
Elf_Mips_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+ int (*handler)(struct module *me, u32 *location, Elf_Addr v);
Elf_Sym *sym;
u32 *location;
- unsigned int i;
+ unsigned int i, type;
Elf_Addr v;
int res;
@@ -223,9 +224,21 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
return -ENOENT;
}
- v = sym->st_value;
+ type = ELF_MIPS_R_TYPE(rel[i]);
+
+ if (type < ARRAY_SIZE(reloc_handlers_rel))
+ handler = reloc_handlers_rel[type];
+ else
+ handler = NULL;
- res = reloc_handlers_rel[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
+ if (!handler) {
+ pr_err("%s: Unknown relocation type %u\n",
+ me->name, type);
+ return -EINVAL;
+ }
+
+ v = sym->st_value;
+ res = handler(me, location, v);
if (res)
return res;
}
--
2.7.0
[toc] | [prev] | [next] | [standalone]
| From | Paul Burton <paul.burton@imgtec.com> |
|---|---|
| Date | 2016-02-04 14:10 +0100 |
| Subject | [PATCH v2 4/4] MIPS: Support R_MIPS_PC{16,21,26} rel-style relocs |
| Message-ID | <qYrPB-Co-43@gated-at.bofh.it> |
| In reply to | #1326772 |
MIPS32 code uses rel-style relocs, and MIPS32r6 modules may include
R_MIPS_PC16, R_MIPS_PC21 & R_MIPS_PC26 relocations. We thus need to
support these relocations in order to load MIPS32r6 kernel modules. This
patch adds such support, which is similar to the rela-style support in
module-rela.c but making use of the implicit addend from the instruction
encoding.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
Changes in v2:
- Unify PC{16,21,26} implementation.
arch/mips/kernel/module.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index e16624f..ff5d97d 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -182,13 +182,62 @@ out_danger:
return -ENOEXEC;
}
+static int apply_r_mips_pc_rel(struct module *me, u32 *location, Elf_Addr v,
+ unsigned bits)
+{
+ unsigned long mask = GENMASK(bits - 1, 0);
+ unsigned long se_bits;
+ long offset;
+
+ if (v % 4) {
+ pr_err("module %s: dangerous R_MIPS_PC%u REL relocation\n",
+ me->name, bits);
+ return -ENOEXEC;
+ }
+
+ /* retrieve & sign extend implicit addend */
+ offset = *location & mask;
+ offset |= (offset & BIT(bits - 1)) ? ~mask : 0;
+
+ offset += ((long)v - (long)location) >> 2;
+
+ /* check the sign bit onwards are identical - ie. we didn't overflow */
+ se_bits = (offset & BIT(bits - 1)) ? ~0ul : 0;
+ if ((offset & ~mask) != (se_bits & ~mask)) {
+ pr_err("module %s: relocation overflow\n", me->name);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & ~mask) | (offset & mask);
+
+ return 0;
+}
+
+static int apply_r_mips_pc16_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ return apply_r_mips_pc_rel(me, location, v, 16);
+}
+
+static int apply_r_mips_pc21_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ return apply_r_mips_pc_rel(me, location, v, 21);
+}
+
+static int apply_r_mips_pc26_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ return apply_r_mips_pc_rel(me, location, v, 26);
+}
+
static int (*reloc_handlers_rel[]) (struct module *me, u32 *location,
Elf_Addr v) = {
[R_MIPS_NONE] = apply_r_mips_none,
[R_MIPS_32] = apply_r_mips_32_rel,
[R_MIPS_26] = apply_r_mips_26_rel,
[R_MIPS_HI16] = apply_r_mips_hi16_rel,
- [R_MIPS_LO16] = apply_r_mips_lo16_rel
+ [R_MIPS_LO16] = apply_r_mips_lo16_rel,
+ [R_MIPS_PC16] = apply_r_mips_pc16_rel,
+ [R_MIPS_PC21_S2] = apply_r_mips_pc21_rel,
+ [R_MIPS_PC26_S2] = apply_r_mips_pc26_rel,
};
int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
--
2.7.0
[toc] | [prev] | [next] | [standalone]
| From | Paul Burton <paul.burton@imgtec.com> |
|---|---|
| Date | 2016-02-04 14:10 +0100 |
| Subject | [PATCH v2 2/4] MIPS: module: Make consistent use of pr_*() |
| Message-ID | <qYrPB-Co-45@gated-at.bofh.it> |
| In reply to | #1326772 |
From: "Steven J. Hill" <Steven.Hill@imgtec.com>
The module relocation handling code has inconsistent use of printk() and
pr_*() functions. Convert printk() calls to use pr_err() and pr_warn().
[paul.burton@imgtec.com: Do the same thing in module.c]
Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
Changes in v2:
- Do the same in module.c.
arch/mips/kernel/module-rela.c | 8 +++-----
arch/mips/kernel/module.c | 7 +++----
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/arch/mips/kernel/module-rela.c b/arch/mips/kernel/module-rela.c
index 9083d63..0570676 100644
--- a/arch/mips/kernel/module-rela.c
+++ b/arch/mips/kernel/module-rela.c
@@ -35,15 +35,13 @@ static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v)
static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
{
if (v % 4) {
- pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n",
+ pr_err("module %s: dangerous R_MIPS_26 RELA relocation\n",
me->name);
return -ENOEXEC;
}
if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
- printk(KERN_ERR
- "module %s: relocation overflow\n",
- me->name);
+ pr_err("module %s: relocation overflow\n", me->name);
return -ENOEXEC;
}
@@ -130,7 +128,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
/* Ignore unresolved weak symbol */
if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
continue;
- printk(KERN_WARNING "%s: Unknown symbol %s\n",
+ pr_warn("%s: Unknown symbol %s\n",
me->name, strtab + sym->st_name);
return -ENOENT;
}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index f9b2936..e16624f 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -73,8 +73,7 @@ static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
}
if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
- printk(KERN_ERR
- "module %s: relocation overflow\n",
+ pr_err("module %s: relocation overflow\n",
me->name);
return -ENOEXEC;
}
@@ -219,8 +218,8 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
/* Ignore unresolved weak symbol */
if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
continue;
- printk(KERN_WARNING "%s: Unknown symbol %s\n",
- me->name, strtab + sym->st_name);
+ pr_warn("%s: Unknown symbol %s\n",
+ me->name, strtab + sym->st_name);
return -ENOENT;
}
--
2.7.0
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web