Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 204809
b: refs/heads/master
c: 8b5f61a
h: refs/heads/master
i:
  204807: a80384a
v: v3
  • Loading branch information
Rusty Russell committed Aug 5, 2010
1 parent 797a06d commit 9b5e6d4
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3264d3f9dd532ed9c3eb9491619e3f485b72747f
refs/heads/master: 8b5f61a795fe37be090b0fd18b6b7271db9298e0
70 changes: 45 additions & 25 deletions trunk/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -2158,6 +2158,7 @@ struct load_info {
} index;
};

/* Sets info->hdr and info->len. */
static int copy_and_check(struct load_info *info, const void __user *umod, unsigned long len)
{
int err;
Expand Down Expand Up @@ -2199,6 +2200,39 @@ static int copy_and_check(struct load_info *info, const void __user *umod, unsig
return err;
}

static int rewrite_section_headers(struct load_info *info)
{
unsigned int i;

/* This should always be true, but let's be sure. */
info->sechdrs[0].sh_addr = 0;

for (i = 1; i < info->hdr->e_shnum; i++) {
Elf_Shdr *shdr = &info->sechdrs[i];
if (shdr->sh_type != SHT_NOBITS
&& info->len < shdr->sh_offset + shdr->sh_size) {
printk(KERN_ERR "Module len %lu truncated\n",
info->len);
return -ENOEXEC;
}

/* Mark all sections sh_addr with their address in the
temporary image. */
shdr->sh_addr = (size_t)info->hdr + shdr->sh_offset;

#ifndef CONFIG_MODULE_UNLOAD
/* Don't load .exit sections */
if (strstarts(info->secstrings+shdr->sh_name, ".exit"))
shdr->sh_flags &= ~(unsigned long)SHF_ALLOC;
#endif
/* Don't keep modinfo and version sections. */
if (!strcmp(info->secstrings+shdr->sh_name, "__versions")
|| !strcmp(info->secstrings+shdr->sh_name, ".modinfo"))
shdr->sh_flags &= ~(unsigned long)SHF_ALLOC;
}
return 0;
}

/*
* Set up our basic convenience variables (pointers to section headers,
* search for module section index etc), and do some basic section
Expand All @@ -2210,33 +2244,27 @@ static int copy_and_check(struct load_info *info, const void __user *umod, unsig
static struct module *setup_load_info(struct load_info *info)
{
unsigned int i;
int err;
struct module *mod;

/* Set up the convenience variables */
info->sechdrs = (void *)info->hdr + info->hdr->e_shoff;
info->secstrings = (void *)info->hdr + info->sechdrs[info->hdr->e_shstrndx].sh_offset;
info->sechdrs[0].sh_addr = 0;

for (i = 1; i < info->hdr->e_shnum; i++) {
if (info->sechdrs[i].sh_type != SHT_NOBITS
&& info->len < info->sechdrs[i].sh_offset + info->sechdrs[i].sh_size)
goto truncated;
info->secstrings = (void *)info->hdr
+ info->sechdrs[info->hdr->e_shstrndx].sh_offset;

/* Mark all sections sh_addr with their address in the
temporary image. */
info->sechdrs[i].sh_addr = (size_t)info->hdr + info->sechdrs[i].sh_offset;
err = rewrite_section_headers(info);
if (err)
return ERR_PTR(err);

/* Internal symbols and strings. */
/* Find internal symbols and strings. */
for (i = 1; i < info->hdr->e_shnum; i++) {
if (info->sechdrs[i].sh_type == SHT_SYMTAB) {
info->index.sym = i;
info->index.str = info->sechdrs[i].sh_link;
info->strtab = (char *)info->hdr + info->sechdrs[info->index.str].sh_offset;
info->strtab = (char *)info->hdr
+ info->sechdrs[info->index.str].sh_offset;
break;
}
#ifndef CONFIG_MODULE_UNLOAD
/* Don't load .exit sections */
if (strstarts(info->secstrings+info->sechdrs[i].sh_name, ".exit"))
info->sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
#endif
}

info->index.mod = find_sec(info->hdr, info->sechdrs, info->secstrings,
Expand All @@ -2258,19 +2286,11 @@ static struct module *setup_load_info(struct load_info *info)
info->index.info = find_sec(info->hdr, info->sechdrs, info->secstrings, ".modinfo");
info->index.pcpu = find_pcpusec(info->hdr, info->sechdrs, info->secstrings);

/* Don't keep modinfo and version sections. */
info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;

/* Check module struct version now, before we try to use module. */
if (!check_modstruct_version(info->sechdrs, info->index.vers, mod))
return ERR_PTR(-ENOEXEC);

return mod;

truncated:
printk(KERN_ERR "Module len %lu truncated\n", info->len);
return ERR_PTR(-ENOEXEC);
}

static int check_modinfo(struct module *mod,
Expand Down

0 comments on commit 9b5e6d4

Please sign in to comment.