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