From nobody@FreeBSD.org  Fri Dec  7 00:01:15 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 7B62016A468
	for <freebsd-gnats-submit@FreeBSD.org>; Fri,  7 Dec 2007 00:01:14 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 1BCEB13C44B
	for <freebsd-gnats-submit@FreeBSD.org>; Fri,  7 Dec 2007 00:01:14 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.2/8.14.2) with ESMTP id lB7018v2076303
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 7 Dec 2007 00:01:08 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.2/8.14.1/Submit) id lB7018tn076302;
	Fri, 7 Dec 2007 00:01:08 GMT
	(envelope-from nobody)
Message-Id: <200712070001.lB7018tn076302@www.freebsd.org>
Date: Fri, 7 Dec 2007 00:01:08 GMT
From: "Pedro F. Giffuni" <giffunip@tutopia.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Linuxulator: ELF Notes vs. brandelf
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         118473
>Category:       kern
>Synopsis:       [linux] ELF Notes vs. brandelf
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    dchagin
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Dec 07 00:10:01 UTC 2007
>Closed-Date:    Sun Mar 15 16:23:55 UTC 2009
>Last-Modified:  Sun Mar 15 16:23:55 UTC 2009
>Originator:     Pedro F. Giffuni
>Release:        6.3-RC1
>Organization:
>Environment:
FreeBSD kakumen.cable.net.co 6.3-RC1 FreeBSD 6.3-RC1 #6: Mon Dec  3 16:11:52 COT 2007     root@kakumen.cable.net.co:/usr/src/sys/amd64/compile/SMP  amd64

>Description:
Since 1999 FreeBSD has always used the standard ELF identification branding for it's binaries:
  http://docs.freebsd.org/cgi/mid.cgi?199902271905.LAA10250

However GNU/Linux chose to misinterpret the standard and is using vendor specific ELF notes instead:
    http://www.netbsd.org/docs/kernel/elf-notes.html

As a result we have had to use brandelf(1) to tag the linux binaries in order to use them with the linux ABI.

As a side note, OpenWatcom does generate properly branded linux binaries.

>How-To-Repeat:
Our linux emulation wiki mentions the following "bug" reported by running the Linux Test Project under the linuxulator:

- report by LTP and/or the linux pkill command: "2.4+ kernel w/o ELF notes? -- report this"
>Fix:
Our loader should probably know about ELF notes and try to use them for the linuxulator when/if the standard EI_OSABI is not present; the linuxulator might also need some additional knowledge from ELF notes. 

While brandelf(1) is still a sound utility to have around, this way we wouldn't require it for GNU platforms.

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->kib 
Responsible-Changed-By: kib 
Responsible-Changed-When: Fri Dec 7 05:39:34 UTC 2007 
Responsible-Changed-Why:  
Grab the PR, it was filled by my request. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=118473 

From: <giffunip@tutopia.com>
To: bug-followup@FreeBSD.org
Cc: kib@FreeBSD.org
Subject: Re: kern/118473: [linux] ELF Notes vs. brandelf
Date: Tue, 09 Dec 2008 00:22:35 +0000

 <html>=0D
 =0D
 <P><BR>
 FWIW,</P>=0D
 <P>The wiki page now&nbsp;also mentions there is a patch available here:</P=
 >=0D
 <P><A href=3D"http://akson.sgh.waw.pl/~saper/FreeBSD/linux/auxvec.diff">htt=
 p://akson.sgh.waw.pl/~saper/FreeBSD/linux/auxvec.diff</A></P>=0D
 <P>&nbsp;</P>=0D
 </html><BR>=

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/118473: commit references a PR
Date: Fri, 13 Mar 2009 16:41:08 +0000 (UTC)

 Author: dchagin
 Date: Fri Mar 13 16:40:51 2009
 New Revision: 189771
 URL: http://svn.freebsd.org/changeset/base/189771
 
 Log:
   Implement new way of branding ELF binaries by looking to a
   ".note.ABI-tag" section.
   
   The search order of a brand is changed, now first of all the
   ".note.ABI-tag" is looked through.
   
   Move code which fetch osreldate for ELF binary to check_note() handler.
   
   PR:		118473
   Approved by:	kib (mentor)
 
 Modified:
   head/sys/amd64/amd64/elf_machdep.c
   head/sys/amd64/linux32/linux32_sysvec.c
   head/sys/arm/arm/elf_machdep.c
   head/sys/compat/ia32/ia32_sysvec.c
   head/sys/compat/svr4/svr4_sysvec.c
   head/sys/i386/i386/elf_machdep.c
   head/sys/i386/linux/linux_sysvec.c
   head/sys/ia64/ia64/elf_machdep.c
   head/sys/kern/imgact_elf.c
   head/sys/mips/mips/elf64_machdep.c
   head/sys/mips/mips/elf_machdep.c
   head/sys/powerpc/powerpc/elf_machdep.c
   head/sys/sparc64/sparc64/elf_machdep.c
   head/sys/sys/imgact_elf.h
 
 Modified: head/sys/amd64/amd64/elf_machdep.c
 ==============================================================================
 --- head/sys/amd64/amd64/elf_machdep.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/amd64/amd64/elf_machdep.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -84,7 +84,8 @@ static Elf64_Brandinfo freebsd_brand_inf
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &elf64_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf64_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
 @@ -99,7 +100,8 @@ static Elf64_Brandinfo freebsd_brand_oin
  	.interp_path	= "/usr/libexec/ld-elf.so.1",
  	.sysvec		= &elf64_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf64_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
 
 Modified: head/sys/amd64/linux32/linux32_sysvec.c
 ==============================================================================
 --- head/sys/amd64/linux32/linux32_sysvec.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/amd64/linux32/linux32_sysvec.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -1047,6 +1047,16 @@ struct sysentvec elf_linux_sysvec = {
  	.sv_flags	= SV_ABI_LINUX | SV_ILP32 | SV_IA32
  };
  
 +static char GNULINUX_ABI_VENDOR[] = "GNU";
 +
 +static Elf_Brandnote linux32_brandnote = {
 +	.hdr.n_namesz	= sizeof(GNULINUX_ABI_VENDOR),
 +	.hdr.n_descsz	= 16,
 +	.hdr.n_type	= 1,
 +	.vendor		= GNULINUX_ABI_VENDOR,
 +	.flags		= 0
 +};
 +
  static Elf32_Brandinfo linux_brand = {
  	.brand		= ELFOSABI_LINUX,
  	.machine	= EM_386,
 @@ -1055,7 +1065,8 @@ static Elf32_Brandinfo linux_brand = {
  	.interp_path	= "/lib/ld-linux.so.1",
  	.sysvec		= &elf_linux_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &linux32_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  static Elf32_Brandinfo linux_glibc2brand = {
 @@ -1066,7 +1077,8 @@ static Elf32_Brandinfo linux_glibc2brand
  	.interp_path	= "/lib/ld-linux.so.2",
  	.sysvec		= &elf_linux_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &linux32_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  Elf32_Brandinfo *linux_brandlist[] = {
 
 Modified: head/sys/arm/arm/elf_machdep.c
 ==============================================================================
 --- head/sys/arm/arm/elf_machdep.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/arm/arm/elf_machdep.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -84,7 +84,8 @@ static Elf32_Brandinfo freebsd_brand_inf
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &elf32_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf32_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
 @@ -99,7 +100,8 @@ static Elf32_Brandinfo freebsd_brand_oin
  	.interp_path	= "/usr/libexec/ld-elf.so.1",
  	.sysvec		= &elf32_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf32_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
 
 Modified: head/sys/compat/ia32/ia32_sysvec.c
 ==============================================================================
 --- head/sys/compat/ia32/ia32_sysvec.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/compat/ia32/ia32_sysvec.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -148,6 +148,7 @@ static Elf32_Brandinfo ia32_brand_info =
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &ia32_freebsd_sysvec,
  	.interp_newpath	= "/libexec/ld-elf32.so.1",
 +	.brand_note	= &elf32_freebsd_brandnote,
  	.flags		= BI_CAN_EXEC_DYN
  };
  
 @@ -163,7 +164,8 @@ static Elf32_Brandinfo ia32_brand_oinfo 
  	.interp_path	= "/usr/libexec/ld-elf.so.1",
  	.sysvec		= &ia32_freebsd_sysvec,
  	.interp_newpath	= "/libexec/ld-elf32.so.1",
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf32_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY,
 
 Modified: head/sys/compat/svr4/svr4_sysvec.c
 ==============================================================================
 --- head/sys/compat/svr4/svr4_sysvec.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/compat/svr4/svr4_sysvec.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -204,6 +204,7 @@ Elf32_Brandinfo svr4_brand = {
  	.interp_path	= "/lib/libc.so.1",
  	.sysvec		= &svr4_sysvec,
  	.interp_newpath	= NULL,
 +	.brand_note	= NULL,
  	.flags		= 0
  };
  
 
 Modified: head/sys/i386/i386/elf_machdep.c
 ==============================================================================
 --- head/sys/i386/i386/elf_machdep.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/i386/i386/elf_machdep.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -84,7 +84,8 @@ static Elf32_Brandinfo freebsd_brand_inf
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &elf32_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf32_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
 @@ -99,7 +100,8 @@ static Elf32_Brandinfo freebsd_brand_oin
  	.interp_path	= "/usr/libexec/ld-elf.so.1",
  	.sysvec		= &elf32_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf32_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
 
 Modified: head/sys/i386/linux/linux_sysvec.c
 ==============================================================================
 --- head/sys/i386/linux/linux_sysvec.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/i386/linux/linux_sysvec.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -1019,6 +1019,16 @@ struct sysentvec elf_linux_sysvec = {
  	.sv_flags	= SV_ABI_LINUX | SV_IA32 | SV_ILP32
  };
  
 +static char GNULINUX_ABI_VENDOR[] = "GNU";
 +
 +static Elf_Brandnote linux_brandnote = {
 +	.hdr.n_namesz	= sizeof(GNULINUX_ABI_VENDOR),
 +	.hdr.n_descsz	= 16,
 +	.hdr.n_type	= 1,
 +	.vendor		= GNULINUX_ABI_VENDOR,
 +	.flags		= 0
 +};
 +
  static Elf32_Brandinfo linux_brand = {
  	.brand		= ELFOSABI_LINUX,
  	.machine	= EM_386,
 @@ -1027,7 +1037,8 @@ static Elf32_Brandinfo linux_brand = {
  	.interp_path	= "/lib/ld-linux.so.1",
  	.sysvec		= &elf_linux_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &linux_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  static Elf32_Brandinfo linux_glibc2brand = {
 @@ -1038,7 +1049,8 @@ static Elf32_Brandinfo linux_glibc2brand
  	.interp_path	= "/lib/ld-linux.so.2",
  	.sysvec		= &elf_linux_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &linux_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  Elf32_Brandinfo *linux_brandlist[] = {
 
 Modified: head/sys/ia64/ia64/elf_machdep.c
 ==============================================================================
 --- head/sys/ia64/ia64/elf_machdep.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/ia64/ia64/elf_machdep.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -92,7 +92,8 @@ static Elf64_Brandinfo freebsd_brand_inf
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &elf64_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf64_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
      (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_info);
 @@ -105,7 +106,8 @@ static Elf64_Brandinfo freebsd_brand_oin
  	.interp_path	= "/usr/libexec/ld-elf.so.1",
  	.sysvec		= &elf64_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf64_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
      (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_oinfo);
 
 Modified: head/sys/kern/imgact_elf.c
 ==============================================================================
 --- head/sys/kern/imgact_elf.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/kern/imgact_elf.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -78,14 +78,16 @@ __FBSDID("$FreeBSD$");
  #define OLD_EI_BRAND	8
  
  static int __elfN(check_header)(const Elf_Ehdr *hdr);
 -static Elf_Brandinfo *__elfN(get_brandinfo)(const Elf_Ehdr *hdr,
 -    const char *interp);
 +static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp,
 +    const char *interp, int32_t *osrel);
  static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
      u_long *entry, size_t pagesize);
  static int __elfN(load_section)(struct vmspace *vmspace, vm_object_t object,
      vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz,
      vm_prot_t prot, size_t pagesize);
  static int __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp);
 +static boolean_t __elfN(check_note)(struct image_params *imgp,
 +    Elf_Brandnote *checknote, int32_t *osrel);
  
  SYSCTL_NODE(_kern, OID_AUTO, __CONCAT(elf, __ELF_WORD_SIZE), CTLFLAG_RW, 0,
      "");
 @@ -107,6 +109,16 @@ static Elf_Brandinfo *elf_brand_list[MAX
  #define	round_page_ps(va, ps)	(((va) + (ps - 1)) & ~(ps - 1))
  #define	aligned(a, t)	(trunc_page_ps((u_long)(a), sizeof(t)) == (u_long)(a))
  
 +static const char FREEBSD_ABI_VENDOR[] = "FreeBSD";
 +
 +Elf_Brandnote __elfN(freebsd_brandnote) = {
 +	.hdr.n_namesz	= sizeof(FREEBSD_ABI_VENDOR),
 +	.hdr.n_descsz	= sizeof(int32_t),
 +	.hdr.n_type	= 1,
 +	.vendor		= FREEBSD_ABI_VENDOR,
 +	.flags		= BN_CAN_FETCH_OSREL
 +};
 +
  int
  __elfN(insert_brand_entry)(Elf_Brandinfo *entry)
  {
 @@ -158,19 +170,32 @@ __elfN(brand_inuse)(Elf_Brandinfo *entry
  }
  
  static Elf_Brandinfo *
 -__elfN(get_brandinfo)(const Elf_Ehdr *hdr, const char *interp)
 +__elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
 +    int32_t *osrel)
  {
 +	const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
  	Elf_Brandinfo *bi;
 +	boolean_t ret;
  	int i;
  
  	/*
 -	 * We support three types of branding -- (1) the ELF EI_OSABI field
 +	 * We support four types of branding -- (1) the ELF EI_OSABI field
  	 * that SCO added to the ELF spec, (2) FreeBSD 3.x's traditional string
 -	 * branding w/in the ELF header, and (3) path of the `interp_path'
 -	 * field.  We should also look for an ".note.ABI-tag" ELF section now
 -	 * in all Linux ELF binaries, FreeBSD 4.1+, and some NetBSD ones.
 +	 * branding w/in the ELF header, (3) path of the `interp_path'
 +	 * field, and (4) the ".note.ABI-tag" ELF section.
  	 */
  
 +	/* Look for an ".note.ABI-tag" ELF section */
 +	for (i = 0; i < MAX_BRANDS; i++) {
 +		bi = elf_brand_list[i];
 +		if (bi != NULL && hdr->e_machine == bi->machine &&
 +		    bi->brand_note != NULL) {
 +			ret = __elfN(check_note)(imgp, bi->brand_note, osrel);
 +			if (ret)
 +				return (bi);
 +		}
 +	}
 +
  	/* If the executable has a brand, search for it in the brand list. */
  	for (i = 0; i < MAX_BRANDS; i++) {
  		bi = elf_brand_list[i];
 @@ -590,13 +615,11 @@ fail:
  	return (error);
  }
  
 -static const char FREEBSD_ABI_VENDOR[] = "FreeBSD";
 -
  static int
  __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
  {
  	const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
 -	const Elf_Phdr *phdr, *pnote = NULL;
 +	const Elf_Phdr *phdr;
  	Elf_Auxargs *elf_auxargs;
  	struct vmspace *vmspace;
  	vm_prot_t prot;
 @@ -604,12 +627,11 @@ __CONCAT(exec_, __elfN(imgact))(struct i
  	u_long text_addr = 0, data_addr = 0;
  	u_long seg_size, seg_addr;
  	u_long addr, entry = 0, proghdr = 0;
 +	int32_t osrel = 0;
  	int error = 0, i;
  	const char *interp = NULL, *newinterp = NULL;
  	Elf_Brandinfo *brand_info;
 -	const Elf_Note *note, *note_end;
  	char *path;
 -	const char *note_name;
  	struct sysentvec *sv;
  
  	/*
 @@ -646,7 +668,7 @@ __CONCAT(exec_, __elfN(imgact))(struct i
  		}
  	}
  
 -	brand_info = __elfN(get_brandinfo)(hdr, interp);
 +	brand_info = __elfN(get_brandinfo)(imgp, interp, &osrel);
  	if (brand_info == NULL) {
  		uprintf("ELF binary type \"%u\" not known.\n",
  		    hdr->e_ident[EI_OSABI]);
 @@ -750,9 +772,6 @@ __CONCAT(exec_, __elfN(imgact))(struct i
  		case PT_PHDR: 	/* Program header table info */
  			proghdr = phdr[i].p_vaddr;
  			break;
 -		case PT_NOTE:
 -			pnote = &phdr[i];
 -			break;
  		default:
  			break;
  		}
 @@ -840,41 +859,7 @@ __CONCAT(exec_, __elfN(imgact))(struct i
  
  	imgp->auxargs = elf_auxargs;
  	imgp->interpreted = 0;
 -
 -	/*
 -	 * Try to fetch the osreldate for FreeBSD binary from the ELF
 -	 * OSABI-note. Only the first page of the image is searched,
 -	 * the same as for headers.
 -	 */
 -	if (pnote != NULL && pnote->p_offset < PAGE_SIZE &&
 -	    pnote->p_offset + pnote->p_filesz < PAGE_SIZE ) {
 -		note = (const Elf_Note *)(imgp->image_header + pnote->p_offset);
 -		if (!aligned(note, Elf32_Addr)) {
 -			free(imgp->auxargs, M_TEMP);
 -			imgp->auxargs = NULL;
 -			return (ENOEXEC);
 -		}
 -		note_end = (const Elf_Note *)(imgp->image_header + pnote->p_offset +
 -		    pnote->p_filesz);
 -		while (note < note_end) {
 -			if (note->n_namesz == sizeof(FREEBSD_ABI_VENDOR) &&
 -			    note->n_descsz == sizeof(int32_t) &&
 -			    note->n_type == 1 /* ABI_NOTETYPE */) {
 -				note_name = (const char *)(note + 1);
 -				if (strncmp(FREEBSD_ABI_VENDOR, note_name,
 -				    sizeof(FREEBSD_ABI_VENDOR)) == 0) {
 -					imgp->proc->p_osrel = *(const int32_t *)
 -					    (note_name +
 -					    round_page_ps(sizeof(FREEBSD_ABI_VENDOR),
 -						sizeof(Elf32_Addr)));
 -					break;
 -				}
 -			}
 -			note = (const Elf_Note *)((const char *)(note + 1) +
 -			    round_page_ps(note->n_namesz, sizeof(Elf32_Addr)) +
 -			    round_page_ps(note->n_descsz, sizeof(Elf32_Addr)));
 -		}
 -	}
 +	imgp->proc->p_osrel = osrel;
  
  	return (error);
  }
 @@ -1336,6 +1321,71 @@ __elfN(putnote)(void *dst, size_t *off, 
  }
  
  /*
 + * Try to find the appropriate ABI-note section for checknote,
 + * fetch the osreldate for binary from the ELF OSABI-note. Only the
 + * first page of the image is searched, the same as for headers.
 + */
 +static boolean_t
 +__elfN(check_note)(struct image_params *imgp, Elf_Brandnote *checknote,
 +    int32_t *osrel)
 +{
 +	const Elf_Note *note, *note_end;
 +	const Elf32_Phdr *phdr, *pnote;
 +	const Elf32_Ehdr *hdr;
 +	const char *note_name;
 +	int i;
 +
 +	pnote = NULL;
 +	hdr = (const Elf32_Ehdr *)imgp->image_header;
 +	phdr = (const Elf32_Phdr *)(imgp->image_header + hdr->e_phoff);
 +
 +	for (i = 0; i < hdr->e_phnum; i++) {
 +		if (phdr[i].p_type == PT_NOTE) {
 +			pnote = &phdr[i];
 +			break;
 +		}
 +	}
 +
 +	if (pnote == NULL || pnote->p_offset >= PAGE_SIZE ||
 +	    pnote->p_offset + pnote->p_filesz >= PAGE_SIZE)
 +		return (FALSE);
 +
 +	note = (const Elf_Note *)(imgp->image_header + pnote->p_offset);
 +	if (!aligned(note, Elf32_Addr))
 +		return (FALSE);
 +	note_end = (const Elf_Note *)(imgp->image_header +
 +	    pnote->p_offset + pnote->p_filesz);
 +	while (note < note_end) {
 +		if (note->n_namesz != checknote->hdr.n_namesz ||
 +		    note->n_descsz != checknote->hdr.n_descsz ||
 +		    note->n_type != checknote->hdr.n_type)
 +			goto nextnote;
 +		note_name = (const char *)(note + 1);
 +		if (strncmp(checknote->vendor, note_name,
 +		    checknote->hdr.n_namesz) != 0)
 +			goto nextnote;
 +
 +		/*
 +		 * Fetch the osreldate for binary
 +		 * from the ELF OSABI-note if necessary.
 +		 */
 +		if ((checknote->flags & BN_CAN_FETCH_OSREL) != 0 &&
 +		    osrel != NULL)
 +			*osrel = *(const int32_t *) (note_name +
 +			    roundup2(checknote->hdr.n_namesz,
 +			    sizeof(Elf32_Addr)));
 +		return (TRUE);
 +
 +nextnote:
 +		note = (const Elf_Note *)((const char *)(note + 1) +
 +		    roundup2(note->n_namesz, sizeof(Elf32_Addr)) +
 +		    roundup2(note->n_descsz, sizeof(Elf32_Addr)));
 +	}
 +
 +	return (FALSE);
 +}
 +
 +/*
   * Tell kern_execve.c about it, with a little help from the linker.
   */
  static struct execsw __elfN(execsw) = {
 
 Modified: head/sys/mips/mips/elf64_machdep.c
 ==============================================================================
 --- head/sys/mips/mips/elf64_machdep.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/mips/mips/elf64_machdep.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -88,6 +88,7 @@ static Elf64_Brandinfo freebsd_brand_gnu
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &elf64_freebsd_sysvec,
  	.interp_path	= "/libexec/ld-elf.so.1",
 +	.brand_note	= &elf64_freebsd_brandnote,
  	.flags		= BI_CAN_EXEC_DYN
  };
  
 @@ -103,6 +104,7 @@ static Elf64_Brandinfo freebsd_brand_inf
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &elf64_freebsd_sysvec,
  	.interp_newpath	= NULL,
 +	.brand_note	= &elf64_freebsd_brandnote,
  	.flags		= 0
  };
  
 
 Modified: head/sys/mips/mips/elf_machdep.c
 ==============================================================================
 --- head/sys/mips/mips/elf_machdep.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/mips/mips/elf_machdep.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -86,6 +86,7 @@ static Elf32_Brandinfo freebsd_brand_inf
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &elf32_freebsd_sysvec,
  	.interp_newpath	= NULL,
 +	.brand_note	= &elf32_freebsd_brandnote,
  	.flags		= 0
  };
  
 
 Modified: head/sys/powerpc/powerpc/elf_machdep.c
 ==============================================================================
 --- head/sys/powerpc/powerpc/elf_machdep.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/powerpc/powerpc/elf_machdep.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -87,7 +87,8 @@ static Elf32_Brandinfo freebsd_brand_inf
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &elf32_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf32_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
 @@ -102,7 +103,8 @@ static Elf32_Brandinfo freebsd_brand_oin
  	.interp_path	= "/usr/libexec/ld-elf.so.1",
  	.sysvec		= &elf32_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf32_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
 
 Modified: head/sys/sparc64/sparc64/elf_machdep.c
 ==============================================================================
 --- head/sys/sparc64/sparc64/elf_machdep.c	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/sparc64/sparc64/elf_machdep.c	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -99,7 +99,8 @@ static Elf64_Brandinfo freebsd_brand_inf
  	.interp_path	= "/libexec/ld-elf.so.1",
  	.sysvec		= &elf64_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf64_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
 @@ -114,7 +115,8 @@ static Elf64_Brandinfo freebsd_brand_oin
  	.interp_path	= "/usr/libexec/ld-elf.so.1",
  	.sysvec		= &elf64_freebsd_sysvec,
  	.interp_newpath	= NULL,
 -	.flags		= BI_CAN_EXEC_DYN,
 +	.brand_note	= &elf64_freebsd_brandnote,
 +	.flags		= BI_CAN_EXEC_DYN
  };
  
  SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
 
 Modified: head/sys/sys/imgact_elf.h
 ==============================================================================
 --- head/sys/sys/imgact_elf.h	Fri Mar 13 16:30:33 2009	(r189770)
 +++ head/sys/sys/imgact_elf.h	Fri Mar 13 16:40:51 2009	(r189771)
 @@ -55,6 +55,13 @@ typedef struct {
  } __ElfN(Auxargs);
  
  typedef struct {
 +	Elf_Note	hdr;
 +	const char *	vendor;
 +	int		flags;
 +#define	BN_CAN_FETCH_OSREL	0x0001
 +} Elf_Brandnote;
 +
 +typedef struct {
  	int brand;
  	int machine;
  	const char *compat_3_brand;	/* pre Binutils 2.10 method (FBSD 3) */
 @@ -62,6 +69,7 @@ typedef struct {
  	const char *interp_path;
  	struct sysentvec *sysvec;
  	const char *interp_newpath;
 +	Elf_Brandnote *brand_note;
  	int flags;
  #define	BI_CAN_EXEC_DYN	0x0001
  } __ElfN(Brandinfo);
 @@ -81,7 +89,7 @@ int	__elfN(coredump)(struct thread *, st
  void	__elfN(dump_thread)(struct thread *, void *, size_t *);
  
  extern int __elfN(fallback_brand);
 -
 +extern Elf_Brandnote __elfN(freebsd_brandnote);
  #endif /* _KERNEL */
  
  #endif /* !_SYS_IMGACT_ELF_H_ */
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
Responsible-Changed-From-To: kib->dchagin 
Responsible-Changed-By: dchagin 
Responsible-Changed-When: Sun Mar 15 15:58:20 UTC 2009 
Responsible-Changed-Why:  
grab it 

http://www.freebsd.org/cgi/query-pr.cgi?pr=118473 
State-Changed-From-To: open->closed 
State-Changed-By: dchagin 
State-Changed-When: Sun Mar 15 16:23:08 UTC 2009 
State-Changed-Why:  
fixed. no MFC. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=118473 
>Unformatted:
