BUGFIX: Linux 1.3.x with ELF!

BUGFIX: Linux 1.3.x with ELF!

Post by Markus Gutsch » Mon, 19 Jun 1995 04:00:00



I have finally been able to trace down the bug in binfmt_elf.c that
prevents ELF binaries from running under v1.3.x kernels. This bug has
been present in older kernels as well, but did not show up because of
the way get_unmapped_area() worked. This fix is relative to v1.3.2. If
you really have to, you could probably apply it to v1.3.[01], but I
would strongly suggest to upgrade to v1.3.2 first as there have been
several changes to binfmt_elf.c with that release (it actually
introduced another bug as well...)

Markus

--- cut here --- cut here --- cut here --- cut here --- cut here --- cut here

*** ./linux-1.3.2.patched/fs/binfmt_elf.c.orig  Sun Jun 18 15:45:32 1995
--- ./linux-1.3.2.patched/fs/binfmt_elf.c       Sun Jun 18 15:49:24 1995
***************
*** 82,88 ****
        }
  }

! unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exec, unsigned int load_addr, int ibcs)
  {
        unsigned long *argv,*envp, *dlinfo;
        unsigned long * sp;
--- 82,88 ----
        }
  }

! unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exec, unsigned int load_addr, unsigned int interp_load_addr, int ibcs)
  {
        unsigned long *argv,*envp, *dlinfo;
        unsigned long * sp;
***************
*** 133,139 ****
          put_fs_long(4,dlinfo++); put_fs_long(sizeof(struct elf_phdr),dlinfo++);
          put_fs_long(5,dlinfo++); put_fs_long(exec->e_phnum,dlinfo++);
          put_fs_long(9,dlinfo++); put_fs_long((unsigned long) exec->e_entry,dlinfo++);
!         put_fs_long(7,dlinfo++); put_fs_long(SHM_RANGE_START,dlinfo++);
          put_fs_long(8,dlinfo++); put_fs_long(0,dlinfo++);
          put_fs_long(6,dlinfo++); put_fs_long(PAGE_SIZE,dlinfo++);
          put_fs_long(0,dlinfo++); put_fs_long(0,dlinfo++);
--- 133,139 ----
          put_fs_long(4,dlinfo++); put_fs_long(sizeof(struct elf_phdr),dlinfo++);
          put_fs_long(5,dlinfo++); put_fs_long(exec->e_phnum,dlinfo++);
          put_fs_long(9,dlinfo++); put_fs_long((unsigned long) exec->e_entry,dlinfo++);
!         put_fs_long(7,dlinfo++); put_fs_long(interp_load_addr,dlinfo++);
          put_fs_long(8,dlinfo++); put_fs_long(0,dlinfo++);
          put_fs_long(6,dlinfo++); put_fs_long(PAGE_SIZE,dlinfo++);
          put_fs_long(0,dlinfo++); put_fs_long(0,dlinfo++);
***************
*** 163,169 ****
     an ELF header */

  static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
!                            struct inode * interpreter_inode)
  {
          struct file * file;
        struct elf_phdr *elf_phdata  =  NULL;
--- 163,169 ----
     an ELF header */

  static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
!                            struct inode * interpreter_inode, unsigned int *interp_load_addr)
  {
          struct file * file;
        struct elf_phdr *elf_phdata  =  NULL;
***************
*** 292,297 ****
--- 292,298 ----
                  MAP_FIXED|MAP_PRIVATE, 0);
        kfree(elf_phdata);

+       *interp_load_addr = load_addr;
        return ((unsigned int) interp_elf_ex->e_entry) + load_addr;
  }

***************
*** 362,368 ****
        unsigned int elf_bss, k, elf_brk;
        int retval;
        char * elf_interpreter;
!       unsigned int elf_entry;
        int status;
        unsigned int start_code, end_code, end_data;
        unsigned int elf_stack;
--- 363,369 ----
        unsigned int elf_bss, k, elf_brk;
        int retval;
        char * elf_interpreter;
!       unsigned int elf_entry, interp_load_addr = 0;
        int status;
        unsigned int start_code, end_code, end_data;
        unsigned int elf_stack;
***************
*** 444,451 ****
  #if 0
                        printk("Using ELF interpreter %s\n", elf_interpreter);
  #endif
!                       if(retval >= 0)
                                retval = namei(elf_interpreter, &interpreter_inode);
                        if(retval >= 0)
                                retval = read_exec(interpreter_inode,0,bprm->buf,128, 1);

--- 445,456 ----
  #if 0
                        printk("Using ELF interpreter %s\n", elf_interpreter);
  #endif
!                       if(retval >= 0) {
!                               old_fs = get_fs(); /* This could probably be optimized */
!                               set_fs(get_ds());
                                retval = namei(elf_interpreter, &interpreter_inode);
+                               set_fs(old_fs); }
+
                        if(retval >= 0)
                                retval = read_exec(interpreter_inode,0,bprm->buf,128, 1);

***************
*** 552,558 ****
                    load_aout_interp(&interp_ex, interpreter_inode);

                  if(interpreter_type & 2) elf_entry =
!                   load_elf_interp(&interp_elf_ex, interpreter_inode);

                  old_fs = get_fs();
                  set_fs(get_ds());
--- 557,563 ----
                    load_aout_interp(&interp_ex, interpreter_inode);

                  if(interpreter_type & 2) elf_entry =
!                   load_elf_interp(&interp_elf_ex, interpreter_inode, &interp_load_addr);

                  old_fs = get_fs();
                  set_fs(get_ds());
***************
*** 631,637 ****
                        bprm->argc,
                        bprm->envc,
                        (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
!                       load_addr,    
                        (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
        if(interpreter_type == INTERPRETER_AOUT)
          current->mm->arg_start += strlen(passed_fileno) + 1;
--- 636,643 ----
                        bprm->argc,
                        bprm->envc,
                        (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
!                       load_addr,
!                       interp_load_addr,
                        (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
        if(interpreter_type == INTERPRETER_AOUT)
          current->mm->arg_start += strlen(passed_fileno) + 1;

 
 
 

1. Linux 1.2.1 -> 1.3 ELF

I am considering upgrading my system from 1.2.1 to 1.3.18 (ELF). I have some
binaries without source code in a.out format which I use a lot. Is it still
possible to run these under ELF or will I have to track down the source and
recompile? (Yes, I know I really ought to have it!)

I am intending to back up /root, /etc, /home, probably var/usr/spool plus
ensure I have a good boot disk. Any other suggestions to ensure I preserve as
much as possible of the 'feel' and functionality of my current set-up.

Any dire warnings I need to know about before I take this step into the
unknown?!

David.

----------------------------------------------------------
                        |
Dr DJ Ellis             |  See our family Homepage at:
London, UK              |  http://ourworld.compuserve.com

                        |
----------------------------------------------------------

2. File name

3. ELF problem on 1.3.x?

4. Linux as a client to non-PDC NT4 Svr--not working

5. ELF + 1.3.x kernel -> kernel header can't be identified

6. Problem with sending or receiving mails

7. 1.3.3X and ELF modules

8. Linux and NetBIOS???

9. Where is kernel 1.3.x for ELF

10. 1.3.x && ELF compile problems

11. COMPILING a 1.3.X kernel with Slackware ELF Dist.

12. 3c509 and 1.3.6x/1.3.7x

13. krb_err.c bugfix and snake Makefile bugfix