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