mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 07:00:48 +00:00
74641f584d
This fixes the problem introduced by commit 3bfacef412 (get rid of special-casing the /sbin/loader on alpha): osf/1 ecoff binary segfaults when binfmt_aout built as module. That happens because aout binary handler gets on the top of the binfmt list due to late registration, and kernel attempts to execute the binary without preparatory work that must be done by binfmt_loader. Fixed by changing the registration order of the default binfmt handlers using list_add_tail() and introducing insert_binfmt() function which places new handler on the top of the binfmt list. This might be generally useful for installing arch-specific frontends for default handlers or just for overriding them. Signed-off-by: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Al Viro <viro@ZenIV.linux.org.uk> Cc: Richard Henderson <rth@twiddle.net Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
52 lines
1.1 KiB
C
52 lines
1.1 KiB
C
#include <linux/init.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/file.h>
|
|
#include <linux/mm_types.h>
|
|
#include <linux/binfmts.h>
|
|
#include <linux/a.out.h>
|
|
|
|
static int load_binary(struct linux_binprm *bprm, struct pt_regs *regs)
|
|
{
|
|
struct exec *eh = (struct exec *)bprm->buf;
|
|
unsigned long loader;
|
|
struct file *file;
|
|
int retval;
|
|
|
|
if (eh->fh.f_magic != 0x183 || (eh->fh.f_flags & 0x3000) != 0x3000)
|
|
return -ENOEXEC;
|
|
|
|
if (bprm->loader)
|
|
return -ENOEXEC;
|
|
|
|
allow_write_access(bprm->file);
|
|
fput(bprm->file);
|
|
bprm->file = NULL;
|
|
|
|
loader = bprm->vma->vm_end - sizeof(void *);
|
|
|
|
file = open_exec("/sbin/loader");
|
|
retval = PTR_ERR(file);
|
|
if (IS_ERR(file))
|
|
return retval;
|
|
|
|
/* Remember if the application is TASO. */
|
|
bprm->taso = eh->ah.entry < 0x100000000UL;
|
|
|
|
bprm->file = file;
|
|
bprm->loader = loader;
|
|
retval = prepare_binprm(bprm);
|
|
if (retval < 0)
|
|
return retval;
|
|
return search_binary_handler(bprm,regs);
|
|
}
|
|
|
|
static struct linux_binfmt loader_format = {
|
|
.load_binary = load_binary,
|
|
};
|
|
|
|
static int __init init_loader_binfmt(void)
|
|
{
|
|
return insert_binfmt(&loader_format);
|
|
}
|
|
arch_initcall(init_loader_binfmt);
|