lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <46EEDF1B.6040309@linux-kernel.at>
Date:	Mon, 17 Sep 2007 22:10:03 +0200
From:	Oliver Falk <oliver@...ux-kernel.at>
To:	linux-kernel@...r.kernel.org, axp-list@...hat.com
Subject: Re: aboot fixes for 2.6.23

Tested and it works fine!

Thx Richard!

-of

Richard Henderson schrieb:
> Recent build changes have added a PT_NOTE entry to the kernel's
> ELF header.  A perfectly valid change, but Alpha's aboot loader
> is none too bright about examining these headers.
> 
> The following patch to aboot-1.0_pre20040408.tar.bz2 makes it
> so that only PT_LOAD entries are considered for loading, as well
> as several other changes required to get the damned thing to
> build again.
> 
> 
> r~
> 
> 
> diff -rup aboot-1.0_pre20040408/Makefile aboot-local/Makefile
> --- aboot-1.0_pre20040408/Makefile	2004-04-08 08:19:01.000000000 -0700
> +++ aboot-local/Makefile	2007-08-13 16:08:01.000000000 -0700
> @@ -32,15 +32,15 @@ export
>  #
>  LOADADDR	= 20000000
>  
> -ABOOT_LDFLAGS = -static -N -Taboot.lds
> +ABOOT_LDFLAGS = -static -N -Taboot.lds --relax
>  
>  CC		= gcc
>  TOP		= $(shell pwd)
>  ifeq ($(TESTING),)
> -CPPFLAGS	= $(CFGDEFS) -I$(TOP)/include
> -CFLAGS		= $(CPPFLAGS) -D__KERNEL__ -Os -Wall -fno-builtin -mno-fp-regs -ffixed-8
> +CPPFLAGS	= $(CFGDEFS) -I$(TOP)/include -I$(KSRC)/include
> +CFLAGS		= $(CPPFLAGS) -D__KERNEL__ -Os -Wall -fno-builtin -mno-fp-regs
>  else
> -CPPFLAGS	= -DTESTING $(CFGDEFS) -I$(TOP)/include
> +CPPFLAGS	= -DTESTING $(CFGDEFS) -I$(TOP)/include -I$(KSRC)/include
>  CFLAGS		= $(CPPFLAGS) -O -g3 -Wall -D__KERNEL__ -ffixed-8
>  endif
>  ASFLAGS		= $(CPPFLAGS)
> diff -rup aboot-1.0_pre20040408/aboot.c aboot-local/aboot.c
> --- aboot-1.0_pre20040408/aboot.c	2004-04-08 10:53:57.000000000 -0700
> +++ aboot-local/aboot.c	2007-08-13 15:46:33.000000000 -0700
> @@ -19,14 +19,13 @@
>   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>   */
>  
> -#include <linux/elf.h>
>  #include <linux/kernel.h>
>  #include <linux/version.h>
> -
>  #include <asm/console.h>
>  #include <asm/hwrpb.h>
>  #include <asm/system.h>
>  
> +#include <elf.h>
>  #include <alloca.h>
>  #include <errno.h>
>  
> @@ -37,16 +36,6 @@
>  #include "utils.h"
>  #include "string.h"
>  
> -#ifndef elf_check_arch
> -# define aboot_elf_check_arch(e)	1
> -#else
> -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
> -#  define aboot_elf_check_arch(e)        elf_check_arch(e)
> -# else
> -#  define aboot_elf_check_arch(e)        elf_check_arch(e->e_machine)
> -# endif
> -#endif
> -
>  struct bootfs *	bfs = 0;		/* filesystem to boot from */
>  char *		dest_addr = 0;
>  jmp_buf		jump_buffer;
> @@ -83,77 +72,86 @@ static unsigned long entry_addr = START_
>  long
>  first_block (const char *buf, long blocksize)
>  {
> -	struct elfhdr *elf;
> -	struct elf_phdr *phdrs;
> +	Elf64_Ehdr *elf;
> +	Elf64_Phdr *phdrs;
> +	int i, j;
>  
> -	elf  = (struct elfhdr *) buf;
> +	elf  = (Elf64_Ehdr *) buf;
>  	
> -	if (elf->e_ident[0] == 0x7f
> -	    && strncmp(elf->e_ident + 1, "ELF", 3) == 0)
> -	{
> -		int i;
> -		/* looks like an ELF binary: */
> -		if (elf->e_type != ET_EXEC) {
> -			printf("aboot: not an executable ELF file\n");
> -			return -1;
> -		}
> -		if (!aboot_elf_check_arch(elf)) {
> -			printf("aboot: ELF executable not for this machine\n");
> -			return -1;
> -		}
> -		if (elf->e_phoff + elf->e_phnum * sizeof(*phdrs) > (unsigned) blocksize) {
> -			printf("aboot: "
> -			       "ELF program headers not in first block (%ld)\n",
> -			       (long) elf->e_phoff);
> +	if (elf->e_ident[0] != 0x7f
> +	    || elf->e_ident[1] != 'E'
> +	    || elf->e_ident[2] != 'L'
> +	    || elf->e_ident[3] != 'F') {
> +		/* Fail silently, it might be a compressed file */
> +		return -1;
> +	}
> +	if (elf->e_ident[EI_CLASS] != ELFCLASS64
> +	    || elf->e_ident[EI_DATA] != ELFDATA2LSB
> +	    || elf->e_machine != EM_ALPHA) {
> +		printf("aboot: ELF executable not for this machine\n");
> +		return -1;
> +	}
> +
> +	/* Looks like an ELF binary. */
> +	if (elf->e_type != ET_EXEC) {
> +		printf("aboot: not an executable ELF file\n");
> +		return -1;
> +	}
> +
> +	if (elf->e_phoff + elf->e_phnum * sizeof(*phdrs)
> +	    > (unsigned) blocksize) {
> +		printf("aboot: ELF program headers not in first block (%ld)\n",
> +		       (long) elf->e_phoff);
> +		return -1;
> +	}
> +
> +	phdrs = (struct elf_phdr *) (buf + elf->e_phoff);
> +	chunks = malloc(sizeof(struct segment) * elf->e_phnum);
> +	start_addr = phdrs[0].p_vaddr; /* assume they are sorted */
> +	entry_addr = elf->e_entry;
> +
> +	for (i = j = 0; i < elf->e_phnum; ++i) {
> +		int status;
> +
> +		if (phdrs[i].p_type != PT_LOAD)
> +			continue;
> +
> +		chunks[j].addr   = phdrs[i].p_vaddr;
> +		chunks[j].offset = phdrs[i].p_offset;
> +		chunks[j].size   = phdrs[i].p_filesz;
> +		printf("aboot: PHDR %d vaddr %#lx offset %#lx size %#lx\n",
> +		       i, chunks[j].addr, chunks[j].offset, chunks[j].size);
> +
> +		status = check_memory(chunks[j].addr, chunks[j].size);
> +		if (status) {
> +			printf("aboot: Can't load kernel.\n"
> +			       "  Memory at %lx - %lx (PHDR %i) "
> +			         "is %s\n",
> +			       chunks[j].addr,
> +			       chunks[j].addr + chunks[j].size - 1,
> +			       i,
> +			       (status == -ENOMEM) ?
> +			          "Not Found" :
> +				  "Busy (Reserved)");
>  			return -1;
>  		}
> -		phdrs = (struct elf_phdr *) (buf + elf->e_phoff);
> -		chunks = malloc(sizeof(struct segment) * elf->e_phnum);
> -		nchunks = elf->e_phnum;
> -		start_addr = phdrs[0].p_vaddr; /* assume they are sorted */
> -		entry_addr = elf->e_entry;
> -#ifdef DEBUG
> -		printf("aboot: %d program headers, start address %#lx, entry %#lx\n",
> -		       nchunks, start_addr, entry_addr);
> -#endif
> -		for (i = 0; i < elf->e_phnum; ++i) {
> -			int status;
> -
> -			chunks[i].addr   = phdrs[i].p_vaddr;
> -			chunks[i].offset = phdrs[i].p_offset;
> -			chunks[i].size   = phdrs[i].p_filesz;
> -#ifdef DEBUG
> -			printf("aboot: segment %d vaddr %#lx offset %#lx size %#lx\n",
> -			       i, chunks[i].addr, chunks[i].offset, chunks[i].size);
> -#endif
> -
> -#ifndef TESTING
> -			status = check_memory(chunks[i].addr, chunks[i].size);
> -			if (status) {
> +
> +		if (phdrs[i].p_memsz > phdrs[i].p_filesz) {
> +			if (bss_size > 0) {
>  				printf("aboot: Can't load kernel.\n"
> -				       "  Memory at %lx - %lx (chunk %i) "
> -				         "is %s\n",
> -				       chunks[i].addr,
> -				       chunks[i].addr + chunks[i].size - 1,
> -				       i,
> -				       (status == -ENOMEM) ?
> -				          "Not Found" :
> -					  "Busy (Reserved)");
> +				       "  Multiple BSS segments"
> +				       " (PHDR %d)\n", i);
>  				return -1;
>  			}
> -#endif
> +			bss_start = (char *) (phdrs[i].p_vaddr +
> +					      phdrs[i].p_filesz);
> +			bss_size = phdrs[i].p_memsz - phdrs[i].p_filesz;
>  		}
> -		bss_start = (char *) (phdrs[elf->e_phnum - 1].p_vaddr +
> -				      phdrs[elf->e_phnum - 1].p_filesz);
> -		bss_size = (phdrs[elf->e_phnum - 1].p_memsz -
> -			    phdrs[elf->e_phnum - 1].p_filesz);
> -#ifdef DEBUG
> -		printf("aboot: bss at 0x%p, size %#lx\n", bss_start, bss_size);
> -#endif
> -	} else {
> -		/* Fail silently, it might be a compressed file */
> -		return -1;
> +
> +		j++;
>  	}
> +	nchunks = j;
> +	printf("aboot: bss at 0x%p, size %#lx\n", bss_start, bss_size);
>  
>  	return 0;
>  }
> diff -rup aboot-1.0_pre20040408/aboot.lds aboot-local/aboot.lds
> --- aboot-1.0_pre20040408/aboot.lds	2001-10-08 16:03:50.000000000 -0700
> +++ aboot-local/aboot.lds	2007-08-13 15:59:46.000000000 -0700
> @@ -1,22 +1,25 @@
>  OUTPUT_FORMAT("elf64-alpha")
>  ENTRY(__start)
> +PHDRS { kernel PT_LOAD; }
>  SECTIONS
>  {
>    . = 0x20000000;
> -  .text : { *(.text) }
> +  .text : { *(.text) } :kernel
>    _etext = .;
>    PROVIDE (etext = .);
> -  .rodata : { *(.rodata) }
> -  .data : { *(.data) CONSTRUCTORS }
> -  .got : { *(.got) }
> -  .sdata : { *(.sdata) }
> +  .rodata : { *(.rodata*) } :kernel
> +  .data : { *(.data*) } :kernel
> +  .got : { *(.got) } :kernel
> +  .sdata : { *(.sdata) } :kernel
>    _edata = .;
>    PROVIDE (edata = .);
> -  .sbss : { *(.sbss) *(.scommon) }
> -  .bss : { *(.bss) *(COMMON) }
> +  .sbss : { *(.sbss) *(.scommon) } :kernel
> +  .bss : { *(.bss) *(COMMON) } :kernel
>    _end = . ;
>    PROVIDE (end = .);
>  
> +  /DISCARD/ : { *(.eh_frame) } 
> +
>    .mdebug 0 : { *(.mdebug) }
>    .note 0 : { *(.note) }
>    .comment 0 : { *(.comment) }
> diff -rup aboot-1.0_pre20040408/cons.c aboot-local/cons.c
> --- aboot-1.0_pre20040408/cons.c	2003-11-30 19:56:34.000000000 -0800
> +++ aboot-local/cons.c	2007-08-13 15:48:45.000000000 -0700
> @@ -1,5 +1,3 @@
> -#include <alloca.h>
> -
>  #include <linux/kernel.h>
>  
>  #include <asm/console.h>
> @@ -20,7 +18,7 @@
>  #endif
>  
>  long cons_dev;			/* console device */
> -extern long int dispatch();	/* Need the full 64 bit return here...*/
> +extern long int dispatch(long, ...);	/* Need the full 64 bit return here...*/
>  
>  long
>  cons_puts(const char *str, long len)
> @@ -82,7 +80,7 @@ cons_getenv(long index, char *envval, lo
>  	 * allocated on the stack (which guaranteed to by 8 byte
>  	 * aligned).
>  	 */
> -	char * tmp = alloca(maxlen);
> +	char tmp[maxlen];
>  	long len;
>  
>  	len = dispatch(CCB_GET_ENV, index, tmp, maxlen - 1);
> diff -rup aboot-1.0_pre20040408/disk.c aboot-local/disk.c
> --- aboot-1.0_pre20040408/disk.c	2004-04-08 11:14:06.000000000 -0700
> +++ aboot-local/disk.c	2007-08-13 15:50:22.000000000 -0700
> @@ -113,7 +113,7 @@ int
>  load_uncompressed (int fd)
>  {
>  	long nread, nblocks;
> -	unsigned char *buf;
> +	char *buf;
>  	int i;
>  
>  	buf = malloc(bfs->blocksize);
> @@ -131,7 +131,7 @@ load_uncompressed (int fd)
>  	
>  		for(i = 0; i < 16; i++) {
>  			for (j = 0; j < 16; j++)
> -				printf("%02X ", buf[j+16*i]);
> +				printf("%02X ", (unsigned char) buf[j+16*i]);
>  			for(j = 0; j < 16; j++) {
>  				c = buf[j+16*i];
>  				printf("%c", (c >= ' ') ? c : ' ');
> diff -rup aboot-1.0_pre20040408/head.S aboot-local/head.S
> --- aboot-1.0_pre20040408/head.S	2001-10-08 16:03:51.000000000 -0700
> +++ aboot-local/head.S	2007-08-13 16:03:57.000000000 -0700
> @@ -19,8 +19,7 @@ __start:
>  	.quad	0,0,0,0,0,0,0,0
>  1:	br	$27,2f
>  2:	ldgp	$29,0($27)
> -	lda	$27,main_
> -	jsr	$26,($27),main_
> +	bsr	$26,main_	!samegp
>  	call_pal PAL_halt
>  	.end __start
>  
> @@ -170,4 +169,4 @@ run_kernel:
>  	mov	$16,$27
>  	mov	$17,$30
>  	jmp	$31,($27)
> -	.end run_kernel
> \ No newline at end of file
> +	.end run_kernel
> 
> _______________________________________________
> axp-list mailing list
> axp-list@...hat.com
> https://www.redhat.com/mailman/listinfo/axp-list

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ