Small oops in 2.0.x while returning from execve

Jean Wolter (jw5@os.inf.tu-dresden.de)
12 Dec 1997 11:29:17 +0100


Hi,

while looking through my system log file (/var/adm/messages) I have
found the following oops:

general protection: 0000
CPU: 0
EIP: 0010:[<0010a6f5>]
EFLAGS: 00010202
eax: 00000000 ebx: 080bb64c ecx: 080c1f0c edx: 00000000
esi: 080bb60c edi: 080c1f0c ebp: bffffc20 esp: 03650fec
ds: 002b es: 002b fs: 002b gs: 002b ss: 0018
Process _kernel.image (pid: 205, process nr: 30, stackpage=03650000)
Stack: f0001000 00000023 00000286 bffffccc 0000002b
Call Trace:
Code: cf 8d 76 00 8d bc 27 00 00 00 00 89 e1 51 f7 41 38 00 00 02

The instruction raising this oops was the 'iret' instruction in
ret_from_sys_call:

0010a670 <ret_from_sys_call>:
10a670: 83 3d 08 de 1c cmpl $0x0,0x1cde08
10a675: 00 00
...
10a6f5: cf iret
10a6f6: 8d 76 00 leal 0x0(%esi),%esi
10a6f9: 8d bc 27 00 00 leal 0x0(%edi,1),%edi
10a6fe: 00 00

The kernel tried to return from an 'execve("_kernel.image")' which was
accidently executed under Linux (It is not a Linux program, but an
experimental kernel). The image is relocated to 0xf0001000 and starts
a 0xf0001000. Somehow it made it through the consistency checks of
'do_load_elf_binary' and ended up in 'start_thread(regs, 0xf0001000,
bprm->p)'. After finishing execve the kernel tried to return to
0xf0001000 using 'iret' which in turn resulted in the above mentioned
oops.

I would propose the following patch to 'start_thread':

jw5@os: ~/src/port/linux/include/asm-i386>cvs diff processor.h
Index: processor.h
===================================================================
RCS file: /home/cvs/linux/include/asm-i386/processor.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 processor.h
--- processor.h 1996/10/09 11:26:19 1.1.1.2
+++ processor.h 1997/12/12 09:03:19
@@ -140,6 +140,9 @@
regs->ds = regs->es = regs->ss = regs->fs = regs->gs = USER_DS;
regs->eip = eip;
regs->esp = esp;
+ if (eip > TASK_SIZE)
+ send_sig(SIGSEGV, current, 0);
+
}

Jean

PS: The executed image looks like follows (the EINV return value of
do_mmap is silently ignored by do_load_elf_binary after trying to map
the text segment, I don't know whether this is a problem or not)

src/arch/_kernel.image: file format elf32-i386
src/arch/_kernel.image
architecture: i386, flags 0x00000012:
EXEC_P, HAS_SYMS
start address 0xf0001000

Program Header:
LOAD off 0x00000060 vaddr 0xf0001000 paddr 0xf0001000 align 2**4
filesz 0x000044b8 memsz 0x000044b8 flags r-x

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000044b8 f0001000 f0001000 00000060 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
...