This source file includes following definitions.
- padzero
- create_elf_tables
- load_elf_interp
- load_aout_interp
- load_elf_binary
- load_elf_library
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12 #ifdef MODULE
13 #include <linux/module.h>
14 #include <linux/version.h>
15 #else
16 #define MOD_INC_USE_COUNT
17 #define MOD_DEC_USE_COUNT
18 #endif
19
20 #include <linux/fs.h>
21 #include <linux/sched.h>
22 #include <linux/mm.h>
23 #include <linux/mman.h>
24 #include <linux/a.out.h>
25 #include <linux/errno.h>
26 #include <linux/signal.h>
27 #include <linux/binfmts.h>
28 #include <linux/string.h>
29 #include <linux/fcntl.h>
30 #include <linux/ptrace.h>
31 #include <linux/malloc.h>
32 #include <linux/shm.h>
33 #include <linux/personality.h>
34
35 #include <asm/segment.h>
36 #include <asm/pgtable.h>
37
38 #include <linux/config.h>
39
40 #include <linux/unistd.h>
41 typedef int (*sysfun_p)(int, ...);
42 extern sysfun_p sys_call_table[];
43 #define SYS(name) (sys_call_table[__NR_##name])
44
45 #define DLINFO_ITEMS 8
46
47 #include <linux/elf.h>
48
49 static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
50 static int load_elf_library(int fd);
51
52 struct linux_binfmt elf_format = {
53 #ifndef MODULE
54 NULL, NULL, load_elf_binary, load_elf_library, NULL
55 #else
56 NULL, &mod_use_count_, load_elf_binary, load_elf_library, NULL
57 #endif
58 };
59
60
61
62
63
64
65
66 static void padzero(unsigned long elf_bss)
67 {
68 unsigned long nbyte;
69 char * fpnt;
70
71 nbyte = elf_bss & (PAGE_SIZE-1);
72 if (nbyte) {
73 nbyte = PAGE_SIZE - nbyte;
74 verify_area(VERIFY_WRITE, (void *) elf_bss, nbyte);
75 fpnt = (char *) elf_bss;
76 do {
77 put_user(0, fpnt++);
78 } while (--nbyte);
79 }
80 }
81
82 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)
83 {
84 unsigned long *argv,*envp, *dlinfo;
85 unsigned long * sp;
86 struct vm_area_struct *mpnt;
87
88 mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL);
89 if (mpnt) {
90 mpnt->vm_task = current;
91 mpnt->vm_start = PAGE_MASK & (unsigned long) p;
92 mpnt->vm_end = TASK_SIZE;
93 mpnt->vm_page_prot = PAGE_COPY;
94 #ifdef VM_STACK_FLAGS
95 mpnt->vm_flags = VM_STACK_FLAGS;
96 mpnt->vm_pte = 0;
97 #else
98 # ifdef VM_GROWSDOWN
99 mpnt->vm_flags = VM_GROWSDOWN;
100 # endif
101 #endif
102 mpnt->vm_inode = NULL;
103 mpnt->vm_offset = 0;
104 mpnt->vm_ops = NULL;
105 insert_vm_struct(current, mpnt);
106 #ifndef VM_GROWSDOWN
107 current->mm->stk_vma = mpnt;
108 #endif
109
110 }
111 sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
112 if(exec) sp -= DLINFO_ITEMS*2;
113 dlinfo = sp;
114 sp -= envc+1;
115 envp = sp;
116 sp -= argc+1;
117 argv = sp;
118 if (!ibcs) {
119 put_user(envp,--sp);
120 put_user(argv,--sp);
121 }
122
123
124
125
126 if(exec) {
127 struct elf_phdr * eppnt;
128 eppnt = (struct elf_phdr *) exec->e_phoff;
129 put_user(3,dlinfo++); put_user(load_addr + exec->e_phoff,dlinfo++);
130 put_user(4,dlinfo++); put_user(sizeof(struct elf_phdr),dlinfo++);
131 put_user(5,dlinfo++); put_user(exec->e_phnum,dlinfo++);
132 put_user(9,dlinfo++); put_user((unsigned long) exec->e_entry,dlinfo++);
133 put_user(7,dlinfo++); put_user(interp_load_addr,dlinfo++);
134 put_user(8,dlinfo++); put_user(0,dlinfo++);
135 put_user(6,dlinfo++); put_user(PAGE_SIZE,dlinfo++);
136 put_user(0,dlinfo++); put_user(0,dlinfo++);
137 }
138
139 put_user((unsigned long)argc,--sp);
140 current->mm->arg_start = (unsigned long) p;
141 while (argc-->0) {
142 put_user(p,argv++);
143 while (get_user(p++)) ;
144 }
145 put_user(0,argv);
146 current->mm->arg_end = current->mm->env_start = (unsigned long) p;
147 while (envc-->0) {
148 put_user(p,envp++);
149 while (get_user(p++)) ;
150 }
151 put_user(0,envp);
152 current->mm->env_end = (unsigned long) p;
153 return sp;
154 }
155
156
157
158
159
160
161
162 static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
163 struct inode * interpreter_inode, unsigned int *interp_load_addr)
164 {
165 struct file * file;
166 struct elf_phdr *elf_phdata = NULL;
167 struct elf_phdr *eppnt;
168 unsigned int len;
169 unsigned int load_addr;
170 int elf_exec_fileno;
171 int elf_bss;
172 int retval;
173 unsigned int last_bss;
174 int error;
175 int i, k;
176
177 elf_bss = 0;
178 last_bss = 0;
179 error = load_addr = 0;
180
181
182 if((interp_elf_ex->e_type != ET_EXEC &&
183 interp_elf_ex->e_type != ET_DYN) ||
184 (interp_elf_ex->e_machine != EM_386 && interp_elf_ex->e_machine != EM_486) ||
185 (!interpreter_inode->i_op ||
186 !interpreter_inode->i_op->default_file_ops->mmap)){
187 return 0xffffffff;
188 }
189
190
191
192 if(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE)
193 return 0xffffffff;
194
195 elf_phdata = (struct elf_phdr *)
196 kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, GFP_KERNEL);
197 if(!elf_phdata) return 0xffffffff;
198
199 retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff, (char *) elf_phdata,
200 sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, 1);
201
202 elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY);
203 if (elf_exec_fileno < 0) return 0xffffffff;
204 file = current->files->fd[elf_exec_fileno];
205
206 eppnt = elf_phdata;
207 for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
208 if(eppnt->p_type == PT_LOAD) {
209 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
210 int elf_prot = 0;
211 unsigned long vaddr = 0;
212 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
213 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
214 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
215 if (interp_elf_ex->e_type == ET_EXEC) {
216 elf_type |= MAP_FIXED;
217 vaddr = eppnt->p_vaddr;
218 }
219
220 error = do_mmap(file,
221 vaddr & 0xfffff000,
222 eppnt->p_filesz + (vaddr & 0xfff),
223 elf_prot,
224 elf_type,
225 eppnt->p_offset & 0xfffff000);
226
227 if(error < 0 && error > -1024) break;
228
229 if(!load_addr && interp_elf_ex->e_type == ET_DYN)
230 load_addr = error;
231
232
233
234
235
236 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
237 if(k > elf_bss) elf_bss = k;
238
239
240
241
242
243 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
244 if(k > last_bss) last_bss = k;
245 }
246
247
248
249 SYS(close)(elf_exec_fileno);
250 if(error < 0 && error > -1024) {
251 kfree(elf_phdata);
252 return 0xffffffff;
253 }
254
255
256
257
258
259
260
261 padzero(elf_bss);
262 len = (elf_bss + 0xfff) & 0xfffff000;
263
264
265 if (last_bss > len)
266 do_mmap(NULL, len, last_bss-len,
267 PROT_READ|PROT_WRITE|PROT_EXEC,
268 MAP_FIXED|MAP_PRIVATE, 0);
269 kfree(elf_phdata);
270
271 *interp_load_addr = load_addr;
272 return ((unsigned int) interp_elf_ex->e_entry) + load_addr;
273 }
274
275 static unsigned int load_aout_interp(struct exec * interp_ex,
276 struct inode * interpreter_inode)
277 {
278 int retval;
279 unsigned int elf_entry;
280
281 current->mm->brk = interp_ex->a_bss +
282 (current->mm->end_data = interp_ex->a_data +
283 (current->mm->end_code = interp_ex->a_text));
284 elf_entry = interp_ex->a_entry;
285
286
287 if (N_MAGIC(*interp_ex) == OMAGIC) {
288 do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
289 PROT_READ|PROT_WRITE|PROT_EXEC,
290 MAP_FIXED|MAP_PRIVATE, 0);
291 retval = read_exec(interpreter_inode, 32, (char *) 0,
292 interp_ex->a_text+interp_ex->a_data, 0);
293 } else if (N_MAGIC(*interp_ex) == ZMAGIC || N_MAGIC(*interp_ex) == QMAGIC) {
294 do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
295 PROT_READ|PROT_WRITE|PROT_EXEC,
296 MAP_FIXED|MAP_PRIVATE, 0);
297 retval = read_exec(interpreter_inode,
298 N_TXTOFF(*interp_ex) ,
299 (char *) N_TXTADDR(*interp_ex),
300 interp_ex->a_text+interp_ex->a_data, 0);
301 } else
302 retval = -1;
303
304 if(retval >= 0)
305 do_mmap(NULL, (interp_ex->a_text + interp_ex->a_data + 0xfff) &
306 0xfffff000, interp_ex->a_bss,
307 PROT_READ|PROT_WRITE|PROT_EXEC,
308 MAP_FIXED|MAP_PRIVATE, 0);
309 if(retval < 0) return 0xffffffff;
310 return elf_entry;
311 }
312
313
314
315
316
317
318 #define INTERPRETER_NONE 0
319 #define INTERPRETER_AOUT 1
320 #define INTERPRETER_ELF 2
321
322
323 static int
324 load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
325 {
326 struct elfhdr elf_ex;
327 struct elfhdr interp_elf_ex;
328 struct file * file;
329 struct exec interp_ex;
330 struct inode *interpreter_inode;
331 unsigned int load_addr;
332 unsigned int interpreter_type = INTERPRETER_NONE;
333 unsigned char ibcs2_interpreter;
334 int i;
335 int old_fs;
336 int error;
337 struct elf_phdr * elf_ppnt, *elf_phdata;
338 int elf_exec_fileno;
339 unsigned int elf_bss, k, elf_brk;
340 int retval;
341 char * elf_interpreter;
342 unsigned int elf_entry, interp_load_addr = 0;
343 int status;
344 unsigned int start_code, end_code, end_data;
345 unsigned int elf_stack;
346 char passed_fileno[6];
347
348 MOD_INC_USE_COUNT;
349
350 ibcs2_interpreter = 0;
351 status = 0;
352 load_addr = 0;
353 elf_ex = *((struct elfhdr *) bprm->buf);
354
355 if (elf_ex.e_ident[0] != 0x7f ||
356 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
357 MOD_DEC_USE_COUNT;
358 return -ENOEXEC;
359 }
360
361
362
363 if(elf_ex.e_type != ET_EXEC ||
364 (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
365 (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
366 !bprm->inode->i_op->default_file_ops->mmap)){
367 MOD_DEC_USE_COUNT;
368 return -ENOEXEC;
369 }
370
371
372
373 elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize *
374 elf_ex.e_phnum, GFP_KERNEL);
375
376 retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
377 elf_ex.e_phentsize * elf_ex.e_phnum, 1);
378 if (retval < 0) {
379 kfree (elf_phdata);
380 MOD_DEC_USE_COUNT;
381 return retval;
382 }
383
384 elf_ppnt = elf_phdata;
385
386 elf_bss = 0;
387 elf_brk = 0;
388
389 elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
390
391 if (elf_exec_fileno < 0) {
392 kfree (elf_phdata);
393 MOD_DEC_USE_COUNT;
394 return elf_exec_fileno;
395 }
396
397 file = current->files->fd[elf_exec_fileno];
398
399 elf_stack = 0xffffffff;
400 elf_interpreter = NULL;
401 start_code = 0;
402 end_code = 0;
403 end_data = 0;
404
405 for(i=0;i < elf_ex.e_phnum; i++){
406 if(elf_ppnt->p_type == PT_INTERP) {
407
408
409
410 elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
411 GFP_KERNEL);
412
413 retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter,
414 elf_ppnt->p_filesz, 1);
415
416
417
418 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
419 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)
420 ibcs2_interpreter = 1;
421 #if 0
422 printk("Using ELF interpreter %s\n", elf_interpreter);
423 #endif
424 if(retval >= 0) {
425 old_fs = get_fs();
426 set_fs(get_ds());
427 retval = namei(elf_interpreter, &interpreter_inode);
428 set_fs(old_fs);
429 }
430
431 if(retval >= 0)
432 retval = read_exec(interpreter_inode,0,bprm->buf,128, 1);
433
434 if(retval >= 0) {
435 interp_ex = *((struct exec *) bprm->buf);
436 interp_elf_ex = *((struct elfhdr *) bprm->buf);
437
438 }
439 if(retval < 0) {
440 kfree (elf_phdata);
441 kfree(elf_interpreter);
442 MOD_DEC_USE_COUNT;
443 return retval;
444 }
445 }
446 elf_ppnt++;
447 }
448
449
450 if(elf_interpreter){
451 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
452 if(retval < 0) {
453 kfree(elf_interpreter);
454 kfree(elf_phdata);
455 MOD_DEC_USE_COUNT;
456 return -ELIBACC;
457 }
458
459 if((N_MAGIC(interp_ex) != OMAGIC) &&
460 (N_MAGIC(interp_ex) != ZMAGIC) &&
461 (N_MAGIC(interp_ex) != QMAGIC))
462 interpreter_type = INTERPRETER_ELF;
463
464 if (interp_elf_ex.e_ident[0] != 0x7f ||
465 strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0)
466 interpreter_type &= ~INTERPRETER_ELF;
467
468 if(!interpreter_type)
469 {
470 kfree(elf_interpreter);
471 kfree(elf_phdata);
472 MOD_DEC_USE_COUNT;
473 return -ELIBBAD;
474 }
475 }
476
477
478
479
480 if (!bprm->sh_bang) {
481 char * passed_p;
482
483 if(interpreter_type == INTERPRETER_AOUT) {
484 sprintf(passed_fileno, "%d", elf_exec_fileno);
485 passed_p = passed_fileno;
486
487 if(elf_interpreter) {
488 bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
489 bprm->argc++;
490 }
491 }
492 if (!bprm->p) {
493 if(elf_interpreter) {
494 kfree(elf_interpreter);
495 }
496 kfree (elf_phdata);
497 MOD_DEC_USE_COUNT;
498 return -E2BIG;
499 }
500 }
501
502
503 flush_old_exec(bprm);
504
505 current->mm->end_data = 0;
506 current->mm->end_code = 0;
507 current->mm->start_mmap = ELF_START_MMAP;
508 current->mm->mmap = NULL;
509 elf_entry = (unsigned int) elf_ex.e_entry;
510
511
512
513 current->mm->rss = 0;
514 bprm->p += setup_arg_pages(0, bprm->page);
515 current->mm->start_stack = bprm->p;
516
517
518
519
520
521
522 old_fs = get_fs();
523 set_fs(get_ds());
524
525 elf_ppnt = elf_phdata;
526 for(i=0;i < elf_ex.e_phnum; i++){
527
528 if(elf_ppnt->p_type == PT_INTERP) {
529
530
531 set_fs(old_fs);
532
533 if(interpreter_type & 1) elf_entry =
534 load_aout_interp(&interp_ex, interpreter_inode);
535
536 if(interpreter_type & 2) elf_entry =
537 load_elf_interp(&interp_elf_ex, interpreter_inode, &interp_load_addr);
538
539 old_fs = get_fs();
540 set_fs(get_ds());
541
542 iput(interpreter_inode);
543 kfree(elf_interpreter);
544
545 if(elf_entry == 0xffffffff) {
546 printk("Unable to load interpreter\n");
547 kfree(elf_phdata);
548 send_sig(SIGSEGV, current, 0);
549 MOD_DEC_USE_COUNT;
550 return 0;
551 }
552 }
553
554
555 if(elf_ppnt->p_type == PT_LOAD) {
556 int elf_prot = (elf_ppnt->p_flags & PF_R) ? PROT_READ : 0;
557 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
558 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
559 error = do_mmap(file,
560 elf_ppnt->p_vaddr & 0xfffff000,
561 elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff),
562 elf_prot,
563 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
564 elf_ppnt->p_offset & 0xfffff000);
565
566 #ifdef LOW_ELF_STACK
567 if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack)
568 elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
569 #endif
570
571 if(!load_addr)
572 load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
573 k = elf_ppnt->p_vaddr;
574 if(k > start_code) start_code = k;
575 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
576 if(k > elf_bss) elf_bss = k;
577 if((elf_ppnt->p_flags | PROT_WRITE) && end_code < k)
578 end_code = k;
579 if(end_data < k) end_data = k;
580 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
581 if(k > elf_brk) elf_brk = k;
582 }
583 elf_ppnt++;
584 }
585 set_fs(old_fs);
586
587 kfree(elf_phdata);
588
589 if(interpreter_type != INTERPRETER_AOUT) SYS(close)(elf_exec_fileno);
590 current->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
591
592 if (current->exec_domain && current->exec_domain->use_count)
593 (*current->exec_domain->use_count)--;
594 if (current->binfmt && current->binfmt->use_count)
595 (*current->binfmt->use_count)--;
596 current->exec_domain = lookup_exec_domain(current->personality);
597 current->binfmt = &elf_format;
598 if (current->exec_domain && current->exec_domain->use_count)
599 (*current->exec_domain->use_count)++;
600 if (current->binfmt && current->binfmt->use_count)
601 (*current->binfmt->use_count)++;
602
603 #ifndef VM_STACK_FLAGS
604 current->executable = bprm->inode;
605 bprm->inode->i_count++;
606 #endif
607 #ifdef LOW_ELF_STACK
608 current->start_stack = p = elf_stack - 4;
609 #endif
610 bprm->p -= MAX_ARG_PAGES*PAGE_SIZE;
611 bprm->p = (unsigned long)
612 create_elf_tables((char *)bprm->p,
613 bprm->argc,
614 bprm->envc,
615 (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
616 load_addr,
617 interp_load_addr,
618 (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
619 if(interpreter_type == INTERPRETER_AOUT)
620 current->mm->arg_start += strlen(passed_fileno) + 1;
621 current->mm->start_brk = current->mm->brk = elf_brk;
622 current->mm->end_code = end_code;
623 current->mm->start_code = start_code;
624 current->mm->end_data = end_data;
625 current->mm->start_stack = bprm->p;
626 current->suid = current->euid = current->fsuid = bprm->e_uid;
627 current->sgid = current->egid = current->fsgid = bprm->e_gid;
628
629
630
631 current->mm->brk = (elf_bss + 0xfff) & 0xfffff000;
632 SYS(brk)((elf_brk + 0xfff) & 0xfffff000);
633
634 padzero(elf_bss);
635
636 #if 0
637 printk("(start_brk) %x\n" , current->mm->start_brk);
638 printk("(end_code) %x\n" , current->mm->end_code);
639 printk("(start_code) %x\n" , current->mm->start_code);
640 printk("(end_data) %x\n" , current->mm->end_data);
641 printk("(start_stack) %x\n" , current->mm->start_stack);
642 printk("(brk) %x\n" , current->mm->brk);
643 #endif
644
645 if( current->personality == PER_SVR4 )
646 {
647
648
649
650
651 error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
652 MAP_FIXED | MAP_PRIVATE, 0);
653 }
654
655 start_thread(regs, elf_entry, bprm->p);
656 if (current->flags & PF_PTRACED)
657 send_sig(SIGTRAP, current, 0);
658 MOD_DEC_USE_COUNT;
659 return 0;
660 }
661
662
663
664
665 static int
666 load_elf_library(int fd){
667 struct file * file;
668 struct elfhdr elf_ex;
669 struct elf_phdr *elf_phdata = NULL;
670 struct inode * inode;
671 unsigned int len;
672 int elf_bss;
673 int retval;
674 unsigned int bss;
675 int error;
676 int i,j, k;
677
678 MOD_INC_USE_COUNT;
679 len = 0;
680 file = current->files->fd[fd];
681 inode = file->f_inode;
682 elf_bss = 0;
683
684 set_fs(KERNEL_DS);
685 if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) {
686 SYS(close)(fd);
687 MOD_DEC_USE_COUNT;
688 return -EACCES;
689 }
690 set_fs(USER_DS);
691
692 if (elf_ex.e_ident[0] != 0x7f ||
693 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
694 MOD_DEC_USE_COUNT;
695 return -ENOEXEC;
696 }
697
698
699 if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
700 (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
701 (!inode->i_op || !inode->i_op->default_file_ops->mmap)){
702 MOD_DEC_USE_COUNT;
703 return -ENOEXEC;
704 }
705
706
707
708 if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) {
709 MOD_DEC_USE_COUNT;
710 return -ENOEXEC;
711 }
712
713 elf_phdata = (struct elf_phdr *)
714 kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
715
716 retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,
717 sizeof(struct elf_phdr) * elf_ex.e_phnum, 1);
718
719 j = 0;
720 for(i=0; i<elf_ex.e_phnum; i++)
721 if((elf_phdata + i)->p_type == PT_LOAD) j++;
722
723 if(j != 1) {
724 kfree(elf_phdata);
725 MOD_DEC_USE_COUNT;
726 return -ENOEXEC;
727 }
728
729 while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
730
731
732 error = do_mmap(file,
733 elf_phdata->p_vaddr & 0xfffff000,
734 elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
735 PROT_READ | PROT_WRITE | PROT_EXEC,
736 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
737 elf_phdata->p_offset & 0xfffff000);
738
739 k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
740 if(k > elf_bss) elf_bss = k;
741
742 SYS(close)(fd);
743 if (error != (elf_phdata->p_vaddr & 0xfffff000)) {
744 kfree(elf_phdata);
745 MOD_DEC_USE_COUNT;
746 return error;
747 }
748
749 padzero(elf_bss);
750
751 len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
752 bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
753 if (bss > len)
754 do_mmap(NULL, len, bss-len,
755 PROT_READ|PROT_WRITE|PROT_EXEC,
756 MAP_FIXED|MAP_PRIVATE, 0);
757 kfree(elf_phdata);
758 MOD_DEC_USE_COUNT;
759 return 0;
760 }
761
762 #ifdef MODULE
763 char kernel_version[] = UTS_RELEASE;
764
765 int init_module(void) {
766
767
768
769
770 register_binfmt(&elf_format);
771 return 0;
772 }
773
774 void cleanup_module( void) {
775
776 if (MOD_IN_USE)
777 printk(KERN_INFO "iBCS: module is in use, remove delayed\n");
778
779
780 unregister_binfmt(&elf_format);
781 }
782 #endif