2008-01-01 13:48:43

by Adrian Bunk

[permalink] [raw]
Subject: [2.6.25 patch] remove a.out interpreter for ELF executables

This patch contains the scheduled removal of the a.out interpreter
support for ELF executables.

Signed-off-by: Adrian Bunk <[email protected]>

---

Documentation/feature-removal-schedule.txt | 11 -
fs/binfmt_elf.c | 142 +--------------------
2 files changed, 13 insertions(+), 140 deletions(-)

aca21a4f123d9844fc03c69c3313c5a715a2fd36
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index e754923..bca1eda 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -107,17 +107,6 @@ Who: Eric Biederman <[email protected]>

---------------------------

-What: a.out interpreter support for ELF executables
-When: 2.6.25
-Files: fs/binfmt_elf.c
-Why: Using a.out interpreters for ELF executables was a feature for
- transition from a.out to ELF. But now it is unlikely to be still
- needed anymore and removing it would simplify the hairy ELF
- loader code.
-Who: Andi Kleen <[email protected]>
-
----------------------------
-
What: remove EXPORT_SYMBOL(kernel_thread)
When: August 2006
Files: arch/*/kernel/*_ksyms.c
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index ba8de7c..30e1a75 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -133,7 +133,7 @@ static int padzero(unsigned long elf_bss)

static int
create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
- int interp_aout, unsigned long load_addr,
+ unsigned long load_addr,
unsigned long interp_load_addr)
{
unsigned long p = bprm->p;
@@ -223,11 +223,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
sp = STACK_ADD(p, ei_index);

items = (argc + 1) + (envc + 1);
- if (interp_aout) {
- items += 3; /* a.out interpreters require argv & envp too */
- } else {
- items += 1; /* ELF interpreters only put argc on the stack */
- }
+ items += 1; /* ELF interpreters only put argc on the stack */
+
bprm->p = STACK_ROUND(sp, items);

/* Point sp at the lowest address on the stack */
@@ -250,16 +247,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
/* Now, let's put argc (and argv, envp if appropriate) on the stack */
if (__put_user(argc, sp++))
return -EFAULT;
- if (interp_aout) {
- argv = sp + 2;
- envp = argv + argc + 1;
- if (__put_user((elf_addr_t)(unsigned long)argv, sp++) ||
- __put_user((elf_addr_t)(unsigned long)envp, sp++))
- return -EFAULT;
- } else {
- argv = sp;
- envp = argv + argc + 1;
- }
+
+ argv = sp;
+ envp = argv + argc + 1;

/* Populate argv and envp */
p = current->mm->arg_end = current->mm->arg_start;
@@ -464,61 +454,11 @@ out:
return error;
}

-static unsigned long load_aout_interp(struct exec *interp_ex,
- struct file *interpreter)
-{
- unsigned long text_data, elf_entry = ~0UL;
- char __user * addr;
- loff_t offset;
-
- current->mm->end_code = interp_ex->a_text;
- text_data = interp_ex->a_text + interp_ex->a_data;
- current->mm->end_data = text_data;
- current->mm->brk = interp_ex->a_bss + text_data;
-
- switch (N_MAGIC(*interp_ex)) {
- case OMAGIC:
- offset = 32;
- addr = (char __user *)0;
- break;
- case ZMAGIC:
- case QMAGIC:
- offset = N_TXTOFF(*interp_ex);
- addr = (char __user *)N_TXTADDR(*interp_ex);
- break;
- default:
- goto out;
- }
-
- down_write(&current->mm->mmap_sem);
- do_brk(0, text_data);
- up_write(&current->mm->mmap_sem);
- if (!interpreter->f_op || !interpreter->f_op->read)
- goto out;
- if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
- goto out;
- flush_icache_range((unsigned long)addr,
- (unsigned long)addr + text_data);
-
- down_write(&current->mm->mmap_sem);
- do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
- interp_ex->a_bss);
- up_write(&current->mm->mmap_sem);
- elf_entry = interp_ex->a_entry;
-
-out:
- return elf_entry;
-}
-
/*
* These are the functions used to load ELF style executables and shared
* libraries. There is no binary dependent code anywhere else.
*/

-#define INTERPRETER_NONE 0
-#define INTERPRETER_AOUT 1
-#define INTERPRETER_ELF 2
-
#ifndef STACK_RND_MASK
#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
#endif
@@ -545,7 +485,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
unsigned long load_addr = 0, load_bias = 0;
int load_addr_set = 0;
char * elf_interpreter = NULL;
- unsigned int interpreter_type = INTERPRETER_NONE;
unsigned char ibcs2_interpreter = 0;
unsigned long error;
struct elf_phdr *elf_ppnt, *elf_phdata;
@@ -556,14 +495,12 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
unsigned long elf_entry, interp_load_addr = 0;
unsigned long start_code, end_code, start_data, end_data;
unsigned long reloc_func_desc = 0;
- char passed_fileno[6];
struct files_struct *files;
int executable_stack = EXSTACK_DEFAULT;
unsigned long def_flags = 0;
struct {
struct elfhdr elf_ex;
struct elfhdr interp_elf_ex;
- struct exec interp_ex;
} *loc;

loc = kmalloc(sizeof(*loc), GFP_KERNEL);
@@ -714,7 +651,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
}

/* Get the exec headers */
- loc->interp_ex = *((struct exec *)bprm->buf);
loc->interp_elf_ex = *((struct elfhdr *)bprm->buf);
break;
}
@@ -733,59 +669,16 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)

/* Some simple consistency checks for the interpreter */
if (elf_interpreter) {
- static int warn;
- interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
-
- /* Now figure out which format our binary is */
- if ((N_MAGIC(loc->interp_ex) != OMAGIC) &&
- (N_MAGIC(loc->interp_ex) != ZMAGIC) &&
- (N_MAGIC(loc->interp_ex) != QMAGIC))
- interpreter_type = INTERPRETER_ELF;
-
- if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
- interpreter_type &= ~INTERPRETER_ELF;
-
- if (interpreter_type == INTERPRETER_AOUT && warn < 10) {
- printk(KERN_WARNING "a.out ELF interpreter %s is "
- "deprecated and will not be supported "
- "after Linux 2.6.25\n", elf_interpreter);
- warn++;
- }
-
- retval = -ELIBBAD;
- if (!interpreter_type)
+ if ((memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0) ||
+ !elf_check_arch(&loc->interp_elf_ex)) {
+ retval = -ELIBBAD;
goto out_free_dentry;
-
- /* Make sure only one type was selected */
- if ((interpreter_type & INTERPRETER_ELF) &&
- interpreter_type != INTERPRETER_ELF) {
- // FIXME - ratelimit this before re-enabling
- // printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
- interpreter_type = INTERPRETER_ELF;
}
- /* Verify the interpreter has a valid arch */
- if ((interpreter_type == INTERPRETER_ELF) &&
- !elf_check_arch(&loc->interp_elf_ex))
- goto out_free_dentry;
} else {
/* Executables without an interpreter also need a personality */
SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
}

- /* OK, we are done with that, now set up the arg stuff,
- and then start this sucker up */
- if ((!bprm->sh_bang) && (interpreter_type == INTERPRETER_AOUT)) {
- char *passed_p = passed_fileno;
- sprintf(passed_fileno, "%d", elf_exec_fileno);
-
- if (elf_interpreter) {
- retval = copy_strings_kernel(1, &passed_p, bprm);
- if (retval)
- goto out_free_dentry;
- bprm->argc++;
- }
- }
-
/* Flush all traces of the currently running executable */
retval = flush_old_exec(bprm);
if (retval)
@@ -961,13 +854,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
}

if (elf_interpreter) {
- if (interpreter_type == INTERPRETER_AOUT)
- elf_entry = load_aout_interp(&loc->interp_ex,
- interpreter);
- else
- elf_entry = load_elf_interp(&loc->interp_elf_ex,
- interpreter,
- &interp_load_addr);
+ elf_entry = load_elf_interp(&loc->interp_elf_ex,
+ interpreter,
+ &interp_load_addr);
if (BAD_ADDR(elf_entry)) {
force_sig(SIGSEGV, current);
retval = IS_ERR((void *)elf_entry) ?
@@ -990,8 +879,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)

kfree(elf_phdata);

- if (interpreter_type != INTERPRETER_AOUT)
- sys_close(elf_exec_fileno);
+ sys_close(elf_exec_fileno);

set_binfmt(&elf_format);

@@ -1006,15 +894,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
retval = create_elf_tables(bprm, &loc->elf_ex,
- (interpreter_type == INTERPRETER_AOUT),
load_addr, interp_load_addr);
if (retval < 0) {
send_sig(SIGKILL, current, 0);
goto out;
}
- /* N.B. passed_fileno might not be initialized? */
- if (interpreter_type == INTERPRETER_AOUT)
- current->mm->arg_start += strlen(passed_fileno) + 1;
current->mm->end_code = end_code;
current->mm->start_code = start_code;
current->mm->start_data = start_data;


2008-01-01 14:36:47

by Andi Kleen

[permalink] [raw]
Subject: Re: [2.6.25 patch] remove a.out interpreter for ELF executables

On Tuesday 01 January 2008 14:47:49 Adrian Bunk wrote:
> This patch contains the scheduled removal of the a.out interpreter
> support for ELF executables.

I already have a similar patch queued

ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-aout-interpreter

Also removal of the old unused iBCS hooks while I was on it

ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-ibcs-support

-Andi

2008-01-05 09:32:18

by Andrew Morton

[permalink] [raw]
Subject: Re: [2.6.25 patch] remove a.out interpreter for ELF executables

On Tue, 1 Jan 2008 15:36:32 +0100 Andi Kleen <[email protected]> wrote:

> On Tuesday 01 January 2008 14:47:49 Adrian Bunk wrote:
> > This patch contains the scheduled removal of the a.out interpreter
> > support for ELF executables.
>
> I already have a similar patch queued
>
> ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-aout-interpreter
>
> Also removal of the old unused iBCS hooks while I was on it
>
> ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-ibcs-support
>

Guys, please take a look at similar patches from David in -mm before even
vaguely thinking of breathing anywhere in the remote vicinity of
fs/binfmt_elf.c (sob).

2008-01-05 09:46:55

by Adrian Bunk

[permalink] [raw]
Subject: Re: [2.6.25 patch] remove a.out interpreter for ELF executables

On Sat, Jan 05, 2008 at 01:30:53AM -0800, Andrew Morton wrote:
> On Tue, 1 Jan 2008 15:36:32 +0100 Andi Kleen <[email protected]> wrote:
>
> > On Tuesday 01 January 2008 14:47:49 Adrian Bunk wrote:
> > > This patch contains the scheduled removal of the a.out interpreter
> > > support for ELF executables.
> >
> > I already have a similar patch queued
> >
> > ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-aout-interpreter
> >
> > Also removal of the old unused iBCS hooks while I was on it
> >
> > ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-ibcs-support
> >
>
> Guys, please take a look at similar patches from David in -mm before even
> vaguely thinking of breathing anywhere in the remote vicinity of
> fs/binfmt_elf.c (sob).

What David's patch does in fs/binfmt_elf.c is to make code conditional -
exactly the code Andi removes as scheduled in 2.6.25. You should be able
to simply drop the fs/binfmt_elf.c parts from
aout-suppress-aout-library-support-if-config_arch_supports_aout.patch.

cu
Adrian

BTW: There are also patch conflicts with git-x86, but since they are not
from David you have yet to ask us to look at them. ;-)

--

"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed

2008-01-05 16:39:24

by David Newall

[permalink] [raw]
Subject: Re: [2.6.25 patch] remove a.out interpreter for ELF executables

On Tue, 1 Jan 2008 15:36:32 +0100 Andi Kleen <[email protected]> wrote:

> ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-aout-interpreter
>
> Also removal of the old unused iBCS hooks while I was on it
>
> ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-ibcs-support

Is iBCS support the basis for SCO & SVr4 support? (These both sound
useful.)

2008-01-06 03:15:55

by Andi Kleen

[permalink] [raw]
Subject: Re: [2.6.25 patch] remove a.out interpreter for ELF executables

On Sun, Jan 06, 2008 at 03:09:01AM +1030, David Newall wrote:
> On Tue, 1 Jan 2008 15:36:32 +0100 Andi Kleen <[email protected]> wrote:
>
>> ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-aout-interpreter
>>
>> Also removal of the old unused iBCS hooks while I was on it
>>
>> ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt/patches/remove-ibcs-support
>
> Is iBCS support the basis for SCO & SVr4 support? (These both sound
> useful.)

Yes, but that always required an external patchkit which AFAIK existed
only for 2.4. The point is that if you have to apply an external
patchkit anyways you can as well apply the small patches for these hooks
too. But it doesn't make sense to carry the (admittedly minor) overhead
for this in all kernels. Also the ELF loader is quite hairy code
and any simplification of it helps.

-Andi