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