2007-02-10 02:32:21

by Parag Warudkar

[permalink] [raw]
Subject: [PATCH] Make aout executables work again


This a reworked, replacement version of
x86-fix-vdso-mapping-for-aout-executables-* series of patches in -mm.

1) Define arch_setup_additional_pages() as weak in linux/interp.h
2) Include linux/interp.h in appropriate places
3) Conditionally call arch_setup_additional_pages() from binfmt_*.c if the
arch defines it
4) EXPORT_SYMBOL_GPL(arch_setup_additional_pages) for all x86{64},
powerpc, sh - binfmt_aout can be built as module
5) Get rid of ARCH_HAS_SETUP_ADDITIONAL_PAGES from various places
6) For x86_64 - define and export arch_setup_additional_pages as a wrapper
over syscall32_setup_pages, call it from ia32_aout.c

Fully tested on x86. (Compile, boot and run the aout binary at
http://ftp.funet.fi/pub/Linux/bin/as86.tar.Z). Other arches - changes are
minimal but still I'll appreciate if someone tests them.

Signed-off-by: Parag Warudkar <[email protected]>

diff -urN --exclude='*git*' --exclude='scripts*' linux-2.6-us/arch/i386/kernel/sysenter.c linux-2.6-wk/arch/i386/kernel/sysenter.c
--- linux-2.6-us/arch/i386/kernel/sysenter.c 2007-02-09 17:29:34.000000000 -0500
+++ linux-2.6-wk/arch/i386/kernel/sysenter.c 2007-02-09 17:54:48.000000000 -0500
@@ -137,6 +137,7 @@
up_write(&mm->mmap_sem);
return ret;
}
+EXPORT_SYMBOL_GPL(arch_setup_additional_pages);

const char *arch_vma_name(struct vm_area_struct *vma)
{
diff -urN --exclude='*git*' --exclude='scripts*' linux-2.6-us/arch/powerpc/kernel/vdso.c linux-2.6-wk/arch/powerpc/kernel/vdso.c
--- linux-2.6-us/arch/powerpc/kernel/vdso.c 2007-02-09 17:29:34.000000000 -0500
+++ linux-2.6-wk/arch/powerpc/kernel/vdso.c 2007-02-09 18:02:09.000000000 -0500
@@ -254,6 +254,7 @@
up_write(&mm->mmap_sem);
return rc;
}
+EXPORT_SYMBOL_GPL(arch_setup_additional_pages);

const char *arch_vma_name(struct vm_area_struct *vma)
{
diff -urN --exclude='*git*' --exclude='scripts*' linux-2.6-us/arch/sh/kernel/vsyscall/vsyscall.c linux-2.6-wk/arch/sh/kernel/vsyscall/vsyscall.c
--- linux-2.6-us/arch/sh/kernel/vsyscall/vsyscall.c 2007-02-09 17:29:34.000000000 -0500
+++ linux-2.6-wk/arch/sh/kernel/vsyscall/vsyscall.c 2007-02-09 18:02:51.000000000 -0500
@@ -85,6 +85,7 @@
up_write(&mm->mmap_sem);
return ret;
}
+EXPORT_SYMBOL_GPL(arch_setup_additional_pages);

const char *arch_vma_name(struct vm_area_struct *vma)
{
diff -urN --exclude='*git*' --exclude='scripts*' linux-2.6-us/arch/x86_64/ia32/ia32_aout.c linux-2.6-wk/arch/x86_64/ia32/ia32_aout.c
--- linux-2.6-us/arch/x86_64/ia32/ia32_aout.c 2007-01-26 18:49:37.000000000 -0500
+++ linux-2.6-wk/arch/x86_64/ia32/ia32_aout.c 2007-02-09 20:29:01.000000000 -0500
@@ -23,6 +23,7 @@
#include <linux/user.h>
#include <linux/slab.h>
#include <linux/binfmts.h>
+#include <linux/interp.h>
#include <linux/personality.h>
#include <linux/init.h>

@@ -410,6 +411,12 @@
send_sig(SIGKILL, current, 0);
return retval;
}
+
+ retval = arch_setup_additional_pages(bprm, EXSTACK_DEFAULT);
+ if (retval < 0) {
+ send_sig(SIGKILL, current, 0);
+ return retval;
+ }

current->mm->start_stack =
(unsigned long)create_aout_tables((char __user *)bprm->p, bprm);
diff -urN --exclude='*git*' --exclude='scripts*' linux-2.6-us/arch/x86_64/ia32/ia32_binfmt.c linux-2.6-wk/arch/x86_64/ia32/ia32_binfmt.c
--- linux-2.6-us/arch/x86_64/ia32/ia32_binfmt.c 2007-01-27 17:23:08.000000000 -0500
+++ linux-2.6-wk/arch/x86_64/ia32/ia32_binfmt.c 2007-02-09 17:58:42.000000000 -0500
@@ -258,10 +258,6 @@

static void elf32_init(struct pt_regs *);

-#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
-#define arch_setup_additional_pages syscall32_setup_pages
-extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
-
#include "../../../fs/binfmt_elf.c"

static void elf32_init(struct pt_regs *regs)
diff -urN --exclude='*git*' --exclude='scripts*' linux-2.6-us/arch/x86_64/ia32/syscall32.c linux-2.6-wk/arch/x86_64/ia32/syscall32.c
--- linux-2.6-us/arch/x86_64/ia32/syscall32.c 2007-02-09 17:29:34.000000000 -0500
+++ linux-2.6-wk/arch/x86_64/ia32/syscall32.c 2007-02-09 18:01:23.000000000 -0500
@@ -48,6 +48,12 @@
return ret;
}

+int arch_setup_additional_pages(struct linux_binprm* bprm, int exstack)
+{
+ return syscall32_setup_pages(bprm, exstack);
+}
+EXPORT_SYMBOL_GPL(arch_setup_additional_pages);
+
const char *arch_vma_name(struct vm_area_struct *vma)
{
if (vma->vm_start == VSYSCALL32_BASE &&
diff -urN --exclude='*git*' --exclude='scripts*' linux-2.6-us/fs/binfmt_aout.c linux-2.6-wk/fs/binfmt_aout.c
--- linux-2.6-us/fs/binfmt_aout.c 2007-01-26 18:49:39.000000000 -0500
+++ linux-2.6-wk/fs/binfmt_aout.c 2007-02-09 17:53:33.000000000 -0500
@@ -22,6 +22,7 @@
#include <linux/user.h>
#include <linux/slab.h>
#include <linux/binfmts.h>
+#include <linux/interp.h>
#include <linux/personality.h>
#include <linux/init.h>

@@ -445,6 +446,14 @@
send_sig(SIGKILL, current, 0);
return retval;
}
+
+ if(arch_setup_additional_pages) {
+ retval = arch_setup_additional_pages(bprm, EXSTACK_DEFAULT);
+ if (retval < 0) {
+ send_sig(SIGKILL, current, 0);
+ return retval;
+ }
+ }

current->mm->start_stack =
(unsigned long) create_aout_tables((char __user *) bprm->p, bprm);
diff -urN --exclude='*git*' --exclude='scripts*' linux-2.6-us/fs/binfmt_elf.c linux-2.6-wk/fs/binfmt_elf.c
--- linux-2.6-us/fs/binfmt_elf.c 2007-01-27 17:23:08.000000000 -0500
+++ linux-2.6-wk/fs/binfmt_elf.c 2007-02-09 17:48:18.000000000 -0500
@@ -20,6 +20,7 @@
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/binfmts.h>
+#include <linux/interp.h>
#include <linux/string.h>
#include <linux/file.h>
#include <linux/fcntl.h>
@@ -974,13 +975,13 @@

set_binfmt(&elf_format);

-#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
- retval = arch_setup_additional_pages(bprm, executable_stack);
- if (retval < 0) {
- send_sig(SIGKILL, current, 0);
- goto out;
+ if (arch_setup_additional_pages) {
+ retval = arch_setup_additional_pages(bprm, executable_stack);
+ if (retval < 0) {
+ send_sig(SIGKILL, current, 0);
+ goto out;
+ }
}
-#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */

compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
diff -urN --exclude='*git*' --exclude='scripts*' linux-2.6-us/include/linux/interp.h linux-2.6-wk/include/linux/interp.h
--- linux-2.6-us/include/linux/interp.h 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6-wk/include/linux/interp.h 2007-02-09 21:26:34.000000000 -0500
@@ -0,0 +1,8 @@
+#ifndef _LINUX_INTERP_H
+#define _LINUX_INTERP_H
+
+struct linux_binprm;
+
+extern int __attribute__((weak))
+ arch_setup_additional_pages(struct linux_binprm*, int);
+#endif /* _LINUX_INTERP_H */


2007-02-10 11:58:43

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH] Make aout executables work again

Parag Warudkar <[email protected]> writes:

> This a reworked, replacement version of
> x86-fix-vdso-mapping-for-aout-executables-* series of patches in -mm.
>
> 1) Define arch_setup_additional_pages() as weak in linux/interp.h
> 2) Include linux/interp.h in appropriate places
> 3) Conditionally call arch_setup_additional_pages() from binfmt_*.c if
> the arch defines it
> 4) EXPORT_SYMBOL_GPL(arch_setup_additional_pages) for all x86{64},
> powerpc, sh - binfmt_aout can be built as module
> 5) Get rid of ARCH_HAS_SETUP_ADDITIONAL_PAGES from various places
> 6) For x86_64 - define and export arch_setup_additional_pages as a
> wrapper over syscall32_setup_pages, call it from ia32_aout.c
>
> Fully tested on x86. (Compile, boot and run the aout binary at
> http://ftp.funet.fi/pub/Linux/bin/as86.tar.Z). Other arches - changes
> are minimal but still I'll appreciate if someone tests them.

I already fixed this in a different way -- just use the stack
trampoline on a.out

Can you double check

ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/aout-no-vdso

works for you?

-Andi

2007-02-10 13:50:09

by Parag Warudkar

[permalink] [raw]
Subject: Re: [PATCH] Make aout executables work again

> I already fixed this in a different way -- just use the stack
> trampoline on a.out
>
> Can you double check
>
> ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/aout-no-vdso
>
> works for you?

Is there a reason why we specifically want to make a distinction
between binfmts having and not having VDSOs and do we want aout to
have the possibility of NOT having VDSO when a) It used to have it
unconditionally b) nothing special is needed in arch or common code to
have it and c) Not letting have it requires special arch-specific
code* ?


[*] I see the patch handles i386 and x86_64 - but I am not sure if
something similar will be needed for the other arches to allow aout
executables in absence of VDSO (powerpc, sh).

Parag

2007-02-10 14:25:20

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH] Make aout executables work again

On Saturday 10 February 2007 14:50, Parag Warudkar wrote:
> > I already fixed this in a different way -- just use the stack
> > trampoline on a.out
> >
> > Can you double check
> >
> > ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/aout-no-vdso
> >
> > works for you?
>
> Is there a reason why we specifically want to make a distinction
> between binfmts having and not having VDSOs and do we want aout to
> have the possibility of NOT having VDSO when a) It used to have it
> unconditionally b) nothing special is needed in arch or common code to
> have it and c) Not letting have it requires special arch-specific
> code* ?

I mainly did it this way because it was quite a lot simpler.
I'm not worrying too much about other strange binfmts to be honest

> [*] I see the patch handles i386 and x86_64 - but I am not sure if
> something similar will be needed for the other arches to allow aout
> executables in absence of VDSO (powerpc, sh).

Neither powerpc nor sh support a.out.

-Andi

2007-02-10 14:41:35

by Parag Warudkar

[permalink] [raw]
Subject: Re: [PATCH] Make aout executables work again

> > Is there a reason why we specifically want to make a distinction
> > between binfmts having and not having VDSOs and do we want aout to
> > have the possibility of NOT having VDSO when a) It used to have it
> > unconditionally b) nothing special is needed in arch or common code to
> > have it and c) Not letting have it requires special arch-specific
> > code* ?
>
> I mainly did it this way because it was quite a lot simpler.
> I'm not worrying too much about other strange binfmts to be honest
>

Well with your suggestion of using weak definition (BTW, I find that
thing cool :)) for arch_setup_additional_pages() I think my patch is
simpler and it preserves existing behavior - it just boils down to
actually calling the already existing function in binfmt_aout.c.


> > [*] I see the patch handles i386 and x86_64 - but I am not sure if
> > something similar will be needed for the other arches to allow aout
> > executables in absence of VDSO (powerpc, sh).
>
> Neither powerpc nor sh support a.out.
>

Ok, that's not a concern then. Not that I care about aout but if a
simple fix can let it have VDSO and prevent special casing, I would
prefer to let it have VDSO and still work - at least in the interest
of preserving existing behavior.

Parag

2007-02-10 15:13:04

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH] Make aout executables work again


> > > [*] I see the patch handles i386 and x86_64 - but I am not sure if
> > > something similar will be needed for the other arches to allow aout
> > > executables in absence of VDSO (powerpc, sh).
> >
> > Neither powerpc nor sh support a.out.
> >
>
> Ok, that's not a concern then. Not that I care about aout but if a
> simple fix can let it have VDSO and prevent special casing, I would
> prefer to let it have VDSO and still work - at least in the interest
> of preserving existing behavior.

Ok reasonable argument.

-Andi