Bug 109910 - LTC5351-Large external array causes SIGILL in 32-bit
LTC5351-Large external array causes SIGILL in 32-bit
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: kernel (Show other bugs)
3.0
powerpc Linux
medium Severity medium
: ---
: ---
Assigned To: Arjan van de Ven
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2003-11-12 16:16 EST by IBM Bug Proxy
Modified: 2007-11-30 17:06 EST (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2003-11-12 16:33:54 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description IBM Bug Proxy 2003-11-12 16:16:10 EST
The following has be reported by IBM LTC:  
Large external array causes SIGILL in 32-bit Please fill in each of
the sections below.

Hardware Environment:
4-way POWER4

Software Environment:
SLES8 RC6

Steps to Reproduce:
/home/xxue/work> cat bigdata.c
int x[3000][3000][30];
int main() {
    return 10;
}

/home/xxue/work> gcc bigdata.c
/home/xxue/work> a.out
Illegal instruction (core dumped)
/home/xxue/work> /opt/cross/bin/powerpc64-linux-gcc bigdata.c
/home/xxue/work> a.out

Actual Results:
SIGILL

Expected Results:
clean pass
Additional Information:
The test cases passes in 64-bit mode.


Here's the patch for RHEL3 (kernel 2.4.21-4.EL):

--- linux-2.4.21-4.EL/fs/binfmt_elf.c	2003-11-11 17:45:13.000000000 +0530
+++ linux-2.4.21-4.EL.patched/fs/binfmt_elf.c	2003-11-11
17:46:49.000000000 
+0530
@@ -80,13 +80,14 @@
 
 #define BAD_ADDR(x)	((unsigned long)(x) > TASK_SIZE)
 
-static void set_brk(unsigned long start, unsigned long end)
+static unsigned set_brk(unsigned long start, unsigned long end)
 {
+	int retval=0;	
 	start = ELF_PAGEALIGN(start);
 	end = ELF_PAGEALIGN(end);
 	if (end <= start)
 		return;
-	do_brk(start, end - start);
+	retval = do_brk(start, end - start);
 }
 
 
@@ -367,7 +368,7 @@
 	unsigned long text_data, elf_entry = ~0UL;
 	char * addr;
 	loff_t offset;
-
+	int retval;
 	current->mm->end_code = interp_ex->a_text;
 	text_data = interp_ex->a_text + interp_ex->a_data;
 	current->mm->end_data = text_data;
@@ -387,7 +388,9 @@
 		goto out;
 	}
 
-	do_brk(0, text_data);
+	retval = do_brk(0, text_data);
+	if(BAD_ADDR(retval))
+		goto out;
 	if (!interpreter->f_op || !interpreter->f_op->read)
 		goto out;
 	if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
@@ -395,8 +398,10 @@
 	flush_icache_range((unsigned long)addr,
 	                   (unsigned long)addr + text_data);
 
-	do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
+	retval = do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
 		interp_ex->a_bss);
+	if(BAD_ADDR(retval))
+		goto out;
 	elf_entry = interp_ex->a_entry;
 
 out:
@@ -720,7 +725,26 @@
 	end_code += load_bias;
 	start_data += load_bias;
 	end_data += load_bias;
+        
+	current->mm->end_code = end_code;
+	current->mm->start_code = start_code;
+	current->mm->start_data = start_data;
+	current->mm->end_data = end_data;
+	current->mm->start_stack = bprm->p;
+
+	/* Calling set_brk effectively mmaps the pages that we need
+	 * for the bss and break sections.
+         * We must do this now before we load the interpreter
+	 * in case we have a huge bss region.
+	 */
+	retval = set_brk(elf_bss, elf_brk);
+	if(retval < 0) {
+		printk(KERN_ERR "unable to map bss section\n");
+		send_sig(SIGSEGV, current, 0);
+		goto out_free_dentry;
+		}	
 
+	padzero(elf_bss);
 	if (elf_interpreter) {
 		if (interpreter_type == INTERPRETER_AOUT)
 			elf_entry = load_aout_interp(&interp_ex,
@@ -764,20 +788,7 @@
 	/* N.B. passed_fileno might not be initialized? */
 	if (interpreter_type == INTERPRETER_AOUT)
 		current->mm->arg_start += strlen(passed_fileno) + 1;
-	current->mm->start_brk = current->mm->brk = elf_brk;
-	current->mm->end_code = end_code;
-	current->mm->start_code = start_code;
-	current->mm->start_data = start_data;
-	current->mm->end_data = end_data;
-	current->mm->start_stack = bprm->p;
-
-	/* Calling set_brk effectively mmaps the pages that we need
-	 * for the bss and break sections
-	 */
-	set_brk(elf_bss, elf_brk);
-
-	padzero(elf_bss);
-
+	
 #if 0
 	printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
 	printk("(end_code) %lx\n" , (long) current->mm->end_code);
Comment 1 Bob Johnson 2003-11-12 16:33:54 EST
Closed, IBM will retest in RHEL 3 environment. 

Note You need to log in before you can comment on or make changes to this bug.