Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern - limit the number of sections with ELF_MAXSHNUM
details: https://anonhg.NetBSD.org/src/rev/d32e65d68485
branches: trunk
changeset: 330448:d32e65d68485
user: maxv <maxv%NetBSD.org@localhost>
date: Wed Jul 09 05:50:51 2014 +0000
description:
- limit the number of sections with ELF_MAXSHNUM
- fix the (symstrindex > hdr->e_shnum) check: it should be >=, otherwise there's an
off-by-one
- fix the (symstrindex < 0) check: the value is unsigned, so it can't be <0. However,
we should ensure that symstrindex!=0 (done with SHN_UNDEF)
- set 'error' as appropriate
- ensure that e_shstrndx < hdr->e_shnum, to prevent out-of-bound reads
Fixes several crashes that could occur when loading a kernel module.
Quick glance from martin@
diffstat:
sys/kern/subr_kobj.c | 39 +++++++++++++++++++++++++--------------
1 files changed, 25 insertions(+), 14 deletions(-)
diffs (94 lines):
diff -r 2743be4be234 -r d32e65d68485 sys/kern/subr_kobj.c
--- a/sys/kern/subr_kobj.c Wed Jul 09 04:54:03 2014 +0000
+++ b/sys/kern/subr_kobj.c Wed Jul 09 05:50:51 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_kobj.c,v 1.48 2014/07/06 15:35:32 maxv Exp $ */
+/* $NetBSD: subr_kobj.c,v 1.49 2014/07/09 05:50:51 maxv Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.48 2014/07/06 15:35:32 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.49 2014/07/09 05:50:51 maxv Exp $");
#include "opt_modular.h"
@@ -225,13 +225,13 @@
/*
* Allocate and read in the section header.
*/
- ko->ko_shdrsz = hdr->e_shnum * hdr->e_shentsize;
- if (ko->ko_shdrsz == 0 || hdr->e_shoff == 0 ||
- hdr->e_shentsize != sizeof(Elf_Shdr)) {
+ if (hdr->e_shnum == 0 || hdr->e_shnum > ELF_MAXSHNUM ||
+ hdr->e_shoff == 0 || hdr->e_shentsize != sizeof(Elf_Shdr)) {
kobj_error(ko, "bad sizes");
error = ENOEXEC;
goto out;
}
+ ko->ko_shdrsz = hdr->e_shnum * sizeof(Elf_Shdr);
error = ko->ko_read(ko, (void **)&shdr, ko->ko_shdrsz, hdr->e_shoff,
true);
if (error != 0) {
@@ -282,7 +282,9 @@
goto out;
}
KASSERT(symtabindex != -1);
- if (symstrindex < 0 || symstrindex > hdr->e_shnum ||
+ KASSERT(symstrindex != -1);
+
+ if (symstrindex == SHN_UNDEF || symstrindex >= hdr->e_shnum ||
shdr[symstrindex].sh_type != SHT_STRTAB) {
kobj_error(ko, "file has invalid symbol strings");
error = ENOEXEC;
@@ -326,6 +328,7 @@
ko->ko_symcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
if (ko->ko_symcnt == 0) {
kobj_error(ko, "no symbol table");
+ error = ENOEXEC;
goto out;
}
error = ko->ko_read(ko, (void **)&ko->ko_symtab,
@@ -342,6 +345,7 @@
ko->ko_strtabsz = shdr[symstrindex].sh_size;
if (ko->ko_strtabsz == 0) {
kobj_error(ko, "no symbol strings");
+ error = ENOEXEC;
goto out;
}
error = ko->ko_read(ko, (void *)&ko->ko_strtab, ko->ko_strtabsz,
@@ -365,16 +369,23 @@
/*
* Do we have a string table for the section names?
*/
- if (hdr->e_shstrndx != 0 && shdr[hdr->e_shstrndx].sh_size != 0 &&
- shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
- ko->ko_shstrtabsz = shdr[hdr->e_shstrndx].sh_size;
- error = ko->ko_read(ko, (void **)&ko->ko_shstrtab,
- shdr[hdr->e_shstrndx].sh_size,
- shdr[hdr->e_shstrndx].sh_offset, true);
- if (error != 0) {
- kobj_error(ko, "read failed %d", error);
+ if (hdr->e_shstrndx != SHN_UNDEF) {
+ if (hdr->e_shstrndx >= hdr->e_shnum) {
+ kobj_error(ko, "bad shstrndx");
+ error = ENOEXEC;
goto out;
}
+ if (shdr[hdr->e_shstrndx].sh_size != 0 &&
+ shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
+ ko->ko_shstrtabsz = shdr[hdr->e_shstrndx].sh_size;
+ error = ko->ko_read(ko, (void **)&ko->ko_shstrtab,
+ shdr[hdr->e_shstrndx].sh_size,
+ shdr[hdr->e_shstrndx].sh_offset, true);
+ if (error != 0) {
+ kobj_error(ko, "read failed %d", error);
+ goto out;
+ }
+ }
}
/*
Home |
Main Index |
Thread Index |
Old Index