[PATCH] FDPIC: Adjust the ELF-FDPIC driver to conform more to the CodingStyle
[safe/jmp/linux-2.6] / fs / binfmt_elf_fdpic.c
1 /* binfmt_elf_fdpic.c: FDPIC ELF binary format
2  *
3  * Copyright (C) 2003, 2004, 2006 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  * Derived from binfmt_elf.c
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version
10  * 2 of the License, or (at your option) any later version.
11  */
12
13 #include <linux/module.h>
14
15 #include <linux/fs.h>
16 #include <linux/stat.h>
17 #include <linux/sched.h>
18 #include <linux/mm.h>
19 #include <linux/mman.h>
20 #include <linux/errno.h>
21 #include <linux/signal.h>
22 #include <linux/binfmts.h>
23 #include <linux/string.h>
24 #include <linux/file.h>
25 #include <linux/fcntl.h>
26 #include <linux/slab.h>
27 #include <linux/highmem.h>
28 #include <linux/personality.h>
29 #include <linux/ptrace.h>
30 #include <linux/init.h>
31 #include <linux/smp_lock.h>
32 #include <linux/elf.h>
33 #include <linux/elf-fdpic.h>
34 #include <linux/elfcore.h>
35
36 #include <asm/uaccess.h>
37 #include <asm/param.h>
38 #include <asm/pgalloc.h>
39
40 typedef char *elf_caddr_t;
41 #ifndef elf_addr_t
42 #define elf_addr_t unsigned long
43 #endif
44
45 #if 0
46 #define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
47 #else
48 #define kdebug(fmt, ...) do {} while(0)
49 #endif
50
51 MODULE_LICENSE("GPL");
52
53 static int load_elf_fdpic_binary(struct linux_binprm *, struct pt_regs *);
54 static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *, struct file *);
55 static int elf_fdpic_map_file(struct elf_fdpic_params *, struct file *,
56                               struct mm_struct *, const char *);
57
58 static int create_elf_fdpic_tables(struct linux_binprm *, struct mm_struct *,
59                                    struct elf_fdpic_params *,
60                                    struct elf_fdpic_params *);
61
62 #ifndef CONFIG_MMU
63 static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *,
64                                             unsigned long *);
65 static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *,
66                                                    struct file *,
67                                                    struct mm_struct *);
68 #endif
69
70 static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *,
71                                              struct file *, struct mm_struct *);
72
73 static struct linux_binfmt elf_fdpic_format = {
74         .module         = THIS_MODULE,
75         .load_binary    = load_elf_fdpic_binary,
76 //      .core_dump      = elf_fdpic_core_dump,
77         .min_coredump   = ELF_EXEC_PAGESIZE,
78 };
79
80 static int __init init_elf_fdpic_binfmt(void)
81 {
82         return register_binfmt(&elf_fdpic_format);
83 }
84
85 static void __exit exit_elf_fdpic_binfmt(void)
86 {
87         unregister_binfmt(&elf_fdpic_format);
88 }
89
90 module_init(init_elf_fdpic_binfmt);
91 module_exit(exit_elf_fdpic_binfmt);
92
93 static int is_elf_fdpic(struct elfhdr *hdr, struct file *file)
94 {
95         if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
96                 return 0;
97         if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN)
98                 return 0;
99         if (!elf_check_arch(hdr) || !elf_check_fdpic(hdr))
100                 return 0;
101         if (!file->f_op || !file->f_op->mmap)
102                 return 0;
103         return 1;
104 }
105
106 /*****************************************************************************/
107 /*
108  * read the program headers table into memory
109  */
110 static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params,
111                                  struct file *file)
112 {
113         struct elf32_phdr *phdr;
114         unsigned long size;
115         int retval, loop;
116
117         if (params->hdr.e_phentsize != sizeof(struct elf_phdr))
118                 return -ENOMEM;
119         if (params->hdr.e_phnum > 65536U / sizeof(struct elf_phdr))
120                 return -ENOMEM;
121
122         size = params->hdr.e_phnum * sizeof(struct elf_phdr);
123         params->phdrs = kmalloc(size, GFP_KERNEL);
124         if (!params->phdrs)
125                 return -ENOMEM;
126
127         retval = kernel_read(file, params->hdr.e_phoff,
128                              (char *) params->phdrs, size);
129         if (retval < 0)
130                 return retval;
131
132         /* determine stack size for this binary */
133         phdr = params->phdrs;
134         for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
135                 if (phdr->p_type != PT_GNU_STACK)
136                         continue;
137
138                 if (phdr->p_flags & PF_X)
139                         params->flags |= ELF_FDPIC_FLAG_EXEC_STACK;
140                 else
141                         params->flags |= ELF_FDPIC_FLAG_NOEXEC_STACK;
142
143                 params->stack_size = phdr->p_memsz;
144                 break;
145         }
146
147         return 0;
148 }
149
150 /*****************************************************************************/
151 /*
152  * load an fdpic binary into various bits of memory
153  */
154 static int load_elf_fdpic_binary(struct linux_binprm *bprm,
155                                  struct pt_regs *regs)
156 {
157         struct elf_fdpic_params exec_params, interp_params;
158         struct elf_phdr *phdr;
159         unsigned long stack_size, entryaddr;
160 #ifndef CONFIG_MMU
161         unsigned long fullsize;
162 #endif
163 #ifdef ELF_FDPIC_PLAT_INIT
164         unsigned long dynaddr;
165 #endif
166         struct file *interpreter = NULL; /* to shut gcc up */
167         char *interpreter_name = NULL;
168         int executable_stack;
169         int retval, i;
170
171         memset(&exec_params, 0, sizeof(exec_params));
172         memset(&interp_params, 0, sizeof(interp_params));
173
174         exec_params.hdr = *(struct elfhdr *) bprm->buf;
175         exec_params.flags = ELF_FDPIC_FLAG_PRESENT | ELF_FDPIC_FLAG_EXECUTABLE;
176
177         /* check that this is a binary we know how to deal with */
178         retval = -ENOEXEC;
179         if (!is_elf_fdpic(&exec_params.hdr, bprm->file))
180                 goto error;
181
182         /* read the program header table */
183         retval = elf_fdpic_fetch_phdrs(&exec_params, bprm->file);
184         if (retval < 0)
185                 goto error;
186
187         /* scan for a program header that specifies an interpreter */
188         phdr = exec_params.phdrs;
189
190         for (i = 0; i < exec_params.hdr.e_phnum; i++, phdr++) {
191                 switch (phdr->p_type) {
192                 case PT_INTERP:
193                         retval = -ENOMEM;
194                         if (phdr->p_filesz > PATH_MAX)
195                                 goto error;
196                         retval = -ENOENT;
197                         if (phdr->p_filesz < 2)
198                                 goto error;
199
200                         /* read the name of the interpreter into memory */
201                         interpreter_name = kmalloc(phdr->p_filesz, GFP_KERNEL);
202                         if (!interpreter_name)
203                                 goto error;
204
205                         retval = kernel_read(bprm->file,
206                                              phdr->p_offset,
207                                              interpreter_name,
208                                              phdr->p_filesz);
209                         if (retval < 0)
210                                 goto error;
211
212                         retval = -ENOENT;
213                         if (interpreter_name[phdr->p_filesz - 1] != '\0')
214                                 goto error;
215
216                         kdebug("Using ELF interpreter %s", interpreter_name);
217
218                         /* replace the program with the interpreter */
219                         interpreter = open_exec(interpreter_name);
220                         retval = PTR_ERR(interpreter);
221                         if (IS_ERR(interpreter)) {
222                                 interpreter = NULL;
223                                 goto error;
224                         }
225
226                         retval = kernel_read(interpreter, 0, bprm->buf,
227                                              BINPRM_BUF_SIZE);
228                         if (retval < 0)
229                                 goto error;
230
231                         interp_params.hdr = *((struct elfhdr *) bprm->buf);
232                         break;
233
234                 case PT_LOAD:
235 #ifdef CONFIG_MMU
236                         if (exec_params.load_addr == 0)
237                                 exec_params.load_addr = phdr->p_vaddr;
238 #endif
239                         break;
240                 }
241
242         }
243
244         if (elf_check_const_displacement(&exec_params.hdr))
245                 exec_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;
246
247         /* perform insanity checks on the interpreter */
248         if (interpreter_name) {
249                 retval = -ELIBBAD;
250                 if (!is_elf_fdpic(&interp_params.hdr, interpreter))
251                         goto error;
252
253                 interp_params.flags = ELF_FDPIC_FLAG_PRESENT;
254
255                 /* read the interpreter's program header table */
256                 retval = elf_fdpic_fetch_phdrs(&interp_params, interpreter);
257                 if (retval < 0)
258                         goto error;
259         }
260
261         stack_size = exec_params.stack_size;
262         if (stack_size < interp_params.stack_size)
263                 stack_size = interp_params.stack_size;
264
265         if (exec_params.flags & ELF_FDPIC_FLAG_EXEC_STACK)
266                 executable_stack = EXSTACK_ENABLE_X;
267         else if (exec_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK)
268                 executable_stack = EXSTACK_DISABLE_X;
269         else if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK)
270                 executable_stack = EXSTACK_ENABLE_X;
271         else if (interp_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK)
272                 executable_stack = EXSTACK_DISABLE_X;
273         else
274                 executable_stack = EXSTACK_DEFAULT;
275
276         retval = -ENOEXEC;
277         if (stack_size == 0)
278                 goto error;
279
280         if (elf_check_const_displacement(&interp_params.hdr))
281                 interp_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;
282
283         /* flush all traces of the currently running executable */
284         retval = flush_old_exec(bprm);
285         if (retval)
286                 goto error;
287
288         /* there's now no turning back... the old userspace image is dead,
289          * defunct, deceased, etc. after this point we have to exit via
290          * error_kill */
291         set_personality(PER_LINUX_FDPIC);
292         set_binfmt(&elf_fdpic_format);
293
294         current->mm->start_code = 0;
295         current->mm->end_code = 0;
296         current->mm->start_stack = 0;
297         current->mm->start_data = 0;
298         current->mm->end_data = 0;
299         current->mm->context.exec_fdpic_loadmap = 0;
300         current->mm->context.interp_fdpic_loadmap = 0;
301
302         current->flags &= ~PF_FORKNOEXEC;
303
304 #ifdef CONFIG_MMU
305         elf_fdpic_arch_lay_out_mm(&exec_params,
306                                   &interp_params,
307                                   &current->mm->start_stack,
308                                   &current->mm->start_brk);
309
310         retval = setup_arg_pages(bprm, current->mm->start_stack,
311                                  executable_stack);
312         if (retval < 0) {
313                 send_sig(SIGKILL, current, 0);
314                 goto error_kill;
315         }
316 #endif
317
318         /* load the executable and interpreter into memory */
319         retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm,
320                                     "executable");
321         if (retval < 0)
322                 goto error_kill;
323
324         if (interpreter_name) {
325                 retval = elf_fdpic_map_file(&interp_params, interpreter,
326                                             current->mm, "interpreter");
327                 if (retval < 0) {
328                         printk(KERN_ERR "Unable to load interpreter\n");
329                         goto error_kill;
330                 }
331
332                 allow_write_access(interpreter);
333                 fput(interpreter);
334                 interpreter = NULL;
335         }
336
337 #ifdef CONFIG_MMU
338         if (!current->mm->start_brk)
339                 current->mm->start_brk = current->mm->end_data;
340
341         current->mm->brk = current->mm->start_brk =
342                 PAGE_ALIGN(current->mm->start_brk);
343
344 #else
345         /* create a stack and brk area big enough for everyone
346          * - the brk heap starts at the bottom and works up
347          * - the stack starts at the top and works down
348          */
349         stack_size = (stack_size + PAGE_SIZE - 1) & PAGE_MASK;
350         if (stack_size < PAGE_SIZE * 2)
351                 stack_size = PAGE_SIZE * 2;
352
353         down_write(&current->mm->mmap_sem);
354         current->mm->start_brk = do_mmap(NULL, 0, stack_size,
355                                          PROT_READ | PROT_WRITE | PROT_EXEC,
356                                          MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN,
357                                          0);
358
359         if (IS_ERR_VALUE(current->mm->start_brk)) {
360                 up_write(&current->mm->mmap_sem);
361                 retval = current->mm->start_brk;
362                 current->mm->start_brk = 0;
363                 goto error_kill;
364         }
365
366         /* expand the stack mapping to use up the entire allocation granule */
367         fullsize = ksize((char *) current->mm->start_brk);
368         if (!IS_ERR_VALUE(do_mremap(current->mm->start_brk, stack_size,
369                                     fullsize, 0, 0)))
370                 stack_size = fullsize;
371         up_write(&current->mm->mmap_sem);
372
373         current->mm->brk = current->mm->start_brk;
374         current->mm->context.end_brk = current->mm->start_brk;
375         current->mm->context.end_brk +=
376                 (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
377         current->mm->start_stack = current->mm->start_brk + stack_size;
378 #endif
379
380         compute_creds(bprm);
381         current->flags &= ~PF_FORKNOEXEC;
382         if (create_elf_fdpic_tables(bprm, current->mm,
383                                     &exec_params, &interp_params) < 0)
384                 goto error_kill;
385
386         kdebug("- start_code  %lx", current->mm->start_code);
387         kdebug("- end_code    %lx", current->mm->end_code);
388         kdebug("- start_data  %lx", current->mm->start_data);
389         kdebug("- end_data    %lx", current->mm->end_data);
390         kdebug("- start_brk   %lx", current->mm->start_brk);
391         kdebug("- brk         %lx", current->mm->brk);
392         kdebug("- start_stack %lx", current->mm->start_stack);
393
394 #ifdef ELF_FDPIC_PLAT_INIT
395         /*
396          * The ABI may specify that certain registers be set up in special
397          * ways (on i386 %edx is the address of a DT_FINI function, for
398          * example.  This macro performs whatever initialization to
399          * the regs structure is required.
400          */
401         dynaddr = interp_params.dynamic_addr ?: exec_params.dynamic_addr;
402         ELF_FDPIC_PLAT_INIT(regs, exec_params.map_addr, interp_params.map_addr,
403                             dynaddr);
404 #endif
405
406         /* everything is now ready... get the userspace context ready to roll */
407         entryaddr = interp_params.entry_addr ?: exec_params.entry_addr;
408         start_thread(regs, entryaddr, current->mm->start_stack);
409
410         if (unlikely(current->ptrace & PT_PTRACED)) {
411                 if (current->ptrace & PT_TRACE_EXEC)
412                         ptrace_notify((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
413                 else
414                         send_sig(SIGTRAP, current, 0);
415         }
416
417         retval = 0;
418
419 error:
420         if (interpreter) {
421                 allow_write_access(interpreter);
422                 fput(interpreter);
423         }
424         kfree(interpreter_name);
425         kfree(exec_params.phdrs);
426         kfree(exec_params.loadmap);
427         kfree(interp_params.phdrs);
428         kfree(interp_params.loadmap);
429         return retval;
430
431         /* unrecoverable error - kill the process */
432 error_kill:
433         send_sig(SIGSEGV, current, 0);
434         goto error;
435
436 }
437
438 /*****************************************************************************/
439 /*
440  * present useful information to the program
441  */
442 static int create_elf_fdpic_tables(struct linux_binprm *bprm,
443                                    struct mm_struct *mm,
444                                    struct elf_fdpic_params *exec_params,
445                                    struct elf_fdpic_params *interp_params)
446 {
447         unsigned long sp, csp, nitems;
448         elf_caddr_t __user *argv, *envp;
449         size_t platform_len = 0, len;
450         char *k_platform;
451         char __user *u_platform, *p;
452         long hwcap;
453         int loop;
454
455         /* we're going to shovel a whole load of stuff onto the stack */
456 #ifdef CONFIG_MMU
457         sp = bprm->p;
458 #else
459         sp = mm->start_stack;
460
461         /* stack the program arguments and environment */
462         if (elf_fdpic_transfer_args_to_stack(bprm, &sp) < 0)
463                 return -EFAULT;
464 #endif
465
466         /* get hold of platform and hardware capabilities masks for the machine
467          * we are running on.  In some cases (Sparc), this info is impossible
468          * to get, in others (i386) it is merely difficult.
469          */
470         hwcap = ELF_HWCAP;
471         k_platform = ELF_PLATFORM;
472         u_platform = NULL;
473
474         if (k_platform) {
475                 platform_len = strlen(k_platform) + 1;
476                 sp -= platform_len;
477                 u_platform = (char __user *) sp;
478                 if (__copy_to_user(u_platform, k_platform, platform_len) != 0)
479                         return -EFAULT;
480         }
481
482 #if defined(__i386__) && defined(CONFIG_SMP)
483         /* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
484          * by the processes running on the same package. One thing we can do is
485          * to shuffle the initial stack for them.
486          *
487          * the conditionals here are unneeded, but kept in to make the code
488          * behaviour the same as pre change unless we have hyperthreaded
489          * processors. This keeps Mr Marcelo Person happier but should be
490          * removed for 2.5
491          */
492         if (smp_num_siblings > 1)
493                 sp = sp - ((current->pid % 64) << 7);
494 #endif
495
496         sp &= ~7UL;
497
498         /* stack the load map(s) */
499         len = sizeof(struct elf32_fdpic_loadmap);
500         len += sizeof(struct elf32_fdpic_loadseg) * exec_params->loadmap->nsegs;
501         sp = (sp - len) & ~7UL;
502         exec_params->map_addr = sp;
503
504         if (copy_to_user((void __user *) sp, exec_params->loadmap, len) != 0)
505                 return -EFAULT;
506
507         current->mm->context.exec_fdpic_loadmap = (unsigned long) sp;
508
509         if (interp_params->loadmap) {
510                 len = sizeof(struct elf32_fdpic_loadmap);
511                 len += sizeof(struct elf32_fdpic_loadseg) *
512                         interp_params->loadmap->nsegs;
513                 sp = (sp - len) & ~7UL;
514                 interp_params->map_addr = sp;
515
516                 if (copy_to_user((void __user *) sp, interp_params->loadmap,
517                                  len) != 0)
518                         return -EFAULT;
519
520                 current->mm->context.interp_fdpic_loadmap = (unsigned long) sp;
521         }
522
523         /* force 16 byte _final_ alignment here for generality */
524 #define DLINFO_ITEMS 13
525
526         nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0);
527 #ifdef DLINFO_ARCH_ITEMS
528         nitems += DLINFO_ARCH_ITEMS;
529 #endif
530
531         csp = sp;
532         sp -= nitems * 2 * sizeof(unsigned long);
533         sp -= (bprm->envc + 1) * sizeof(char *);        /* envv[] */
534         sp -= (bprm->argc + 1) * sizeof(char *);        /* argv[] */
535         sp -= 1 * sizeof(unsigned long);                /* argc */
536
537         csp -= sp & 15UL;
538         sp -= sp & 15UL;
539
540         /* put the ELF interpreter info on the stack */
541 #define NEW_AUX_ENT(nr, id, val)                                        \
542         do {                                                            \
543                 struct { unsigned long _id, _val; } __user *ent;        \
544                                                                         \
545                 ent = (void __user *) csp;                              \
546                 __put_user((id), &ent[nr]._id);                         \
547                 __put_user((val), &ent[nr]._val);                       \
548         } while (0)
549
550         csp -= 2 * sizeof(unsigned long);
551         NEW_AUX_ENT(0, AT_NULL, 0);
552         if (k_platform) {
553                 csp -= 2 * sizeof(unsigned long);
554                 NEW_AUX_ENT(0, AT_PLATFORM,
555                             (elf_addr_t) (unsigned long) u_platform);
556         }
557
558         csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
559         NEW_AUX_ENT( 0, AT_HWCAP,       hwcap);
560         NEW_AUX_ENT( 1, AT_PAGESZ,      PAGE_SIZE);
561         NEW_AUX_ENT( 2, AT_CLKTCK,      CLOCKS_PER_SEC);
562         NEW_AUX_ENT( 3, AT_PHDR,        exec_params->ph_addr);
563         NEW_AUX_ENT( 4, AT_PHENT,       sizeof(struct elf_phdr));
564         NEW_AUX_ENT( 5, AT_PHNUM,       exec_params->hdr.e_phnum);
565         NEW_AUX_ENT( 6, AT_BASE,        interp_params->elfhdr_addr);
566         NEW_AUX_ENT( 7, AT_FLAGS,       0);
567         NEW_AUX_ENT( 8, AT_ENTRY,       exec_params->entry_addr);
568         NEW_AUX_ENT( 9, AT_UID,         (elf_addr_t) current->uid);
569         NEW_AUX_ENT(10, AT_EUID,        (elf_addr_t) current->euid);
570         NEW_AUX_ENT(11, AT_GID,         (elf_addr_t) current->gid);
571         NEW_AUX_ENT(12, AT_EGID,        (elf_addr_t) current->egid);
572
573 #ifdef ARCH_DLINFO
574         /* ARCH_DLINFO must come last so platform specific code can enforce
575          * special alignment requirements on the AUXV if necessary (eg. PPC).
576          */
577         ARCH_DLINFO;
578 #endif
579 #undef NEW_AUX_ENT
580
581         /* allocate room for argv[] and envv[] */
582         csp -= (bprm->envc + 1) * sizeof(elf_caddr_t);
583         envp = (elf_caddr_t __user *) csp;
584         csp -= (bprm->argc + 1) * sizeof(elf_caddr_t);
585         argv = (elf_caddr_t __user *) csp;
586
587         /* stack argc */
588         csp -= sizeof(unsigned long);
589         __put_user(bprm->argc, (unsigned long __user *) csp);
590
591         BUG_ON(csp != sp);
592
593         /* fill in the argv[] array */
594 #ifdef CONFIG_MMU
595         current->mm->arg_start = bprm->p;
596 #else
597         current->mm->arg_start = current->mm->start_stack -
598                 (MAX_ARG_PAGES * PAGE_SIZE - bprm->p);
599 #endif
600
601         p = (char __user *) current->mm->arg_start;
602         for (loop = bprm->argc; loop > 0; loop--) {
603                 __put_user((elf_caddr_t) p, argv++);
604                 len = strnlen_user(p, PAGE_SIZE * MAX_ARG_PAGES);
605                 if (!len || len > PAGE_SIZE * MAX_ARG_PAGES)
606                         return -EINVAL;
607                 p += len;
608         }
609         __put_user(NULL, argv);
610         current->mm->arg_end = (unsigned long) p;
611
612         /* fill in the envv[] array */
613         current->mm->env_start = (unsigned long) p;
614         for (loop = bprm->envc; loop > 0; loop--) {
615                 __put_user((elf_caddr_t)(unsigned long) p, envp++);
616                 len = strnlen_user(p, PAGE_SIZE * MAX_ARG_PAGES);
617                 if (!len || len > PAGE_SIZE * MAX_ARG_PAGES)
618                         return -EINVAL;
619                 p += len;
620         }
621         __put_user(NULL, envp);
622         current->mm->env_end = (unsigned long) p;
623
624         mm->start_stack = (unsigned long) sp;
625         return 0;
626 }
627
628 /*****************************************************************************/
629 /*
630  * transfer the program arguments and environment from the holding pages onto
631  * the stack
632  */
633 #ifndef CONFIG_MMU
634 static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm,
635                                             unsigned long *_sp)
636 {
637         unsigned long index, stop, sp;
638         char *src;
639         int ret = 0;
640
641         stop = bprm->p >> PAGE_SHIFT;
642         sp = *_sp;
643
644         for (index = MAX_ARG_PAGES - 1; index >= stop; index--) {
645                 src = kmap(bprm->page[index]);
646                 sp -= PAGE_SIZE;
647                 if (copy_to_user((void *) sp, src, PAGE_SIZE) != 0)
648                         ret = -EFAULT;
649                 kunmap(bprm->page[index]);
650                 if (ret < 0)
651                         goto out;
652         }
653
654         *_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15;
655
656 out:
657         return ret;
658 }
659 #endif
660
661 /*****************************************************************************/
662 /*
663  * load the appropriate binary image (executable or interpreter) into memory
664  * - we assume no MMU is available
665  * - if no other PIC bits are set in params->hdr->e_flags
666  *   - we assume that the LOADable segments in the binary are independently relocatable
667  *   - we assume R/O executable segments are shareable
668  * - else
669  *   - we assume the loadable parts of the image to require fixed displacement
670  *   - the image is not shareable
671  */
672 static int elf_fdpic_map_file(struct elf_fdpic_params *params,
673                               struct file *file,
674                               struct mm_struct *mm,
675                               const char *what)
676 {
677         struct elf32_fdpic_loadmap *loadmap;
678 #ifdef CONFIG_MMU
679         struct elf32_fdpic_loadseg *mseg;
680 #endif
681         struct elf32_fdpic_loadseg *seg;
682         struct elf32_phdr *phdr;
683         unsigned long load_addr, stop;
684         unsigned nloads, tmp;
685         size_t size;
686         int loop, ret;
687
688         /* allocate a load map table */
689         nloads = 0;
690         for (loop = 0; loop < params->hdr.e_phnum; loop++)
691                 if (params->phdrs[loop].p_type == PT_LOAD)
692                         nloads++;
693
694         if (nloads == 0)
695                 return -ELIBBAD;
696
697         size = sizeof(*loadmap) + nloads * sizeof(*seg);
698         loadmap = kmalloc(size, GFP_KERNEL);
699         if (!loadmap)
700                 return -ENOMEM;
701
702         params->loadmap = loadmap;
703         memset(loadmap, 0, size);
704
705         loadmap->version = ELF32_FDPIC_LOADMAP_VERSION;
706         loadmap->nsegs = nloads;
707
708         load_addr = params->load_addr;
709         seg = loadmap->segs;
710
711         /* map the requested LOADs into the memory space */
712         switch (params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) {
713         case ELF_FDPIC_FLAG_CONSTDISP:
714         case ELF_FDPIC_FLAG_CONTIGUOUS:
715 #ifndef CONFIG_MMU
716                 ret = elf_fdpic_map_file_constdisp_on_uclinux(params, file, mm);
717                 if (ret < 0)
718                         return ret;
719                 break;
720 #endif
721         default:
722                 ret = elf_fdpic_map_file_by_direct_mmap(params, file, mm);
723                 if (ret < 0)
724                         return ret;
725                 break;
726         }
727
728         /* map the entry point */
729         if (params->hdr.e_entry) {
730                 seg = loadmap->segs;
731                 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
732                         if (params->hdr.e_entry >= seg->p_vaddr &&
733                             params->hdr.e_entry < seg->p_vaddr + seg->p_memsz) {
734                                 params->entry_addr =
735                                         (params->hdr.e_entry - seg->p_vaddr) +
736                                         seg->addr;
737                                 break;
738                         }
739                 }
740         }
741
742         /* determine where the program header table has wound up if mapped */
743         stop = params->hdr.e_phoff;
744         stop += params->hdr.e_phnum * sizeof (struct elf_phdr);
745         phdr = params->phdrs;
746
747         for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
748                 if (phdr->p_type != PT_LOAD)
749                         continue;
750
751                 if (phdr->p_offset > params->hdr.e_phoff ||
752                     phdr->p_offset + phdr->p_filesz < stop)
753                         continue;
754
755                 seg = loadmap->segs;
756                 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
757                         if (phdr->p_vaddr >= seg->p_vaddr &&
758                             phdr->p_vaddr + phdr->p_filesz <=
759                             seg->p_vaddr + seg->p_memsz) {
760                                 params->ph_addr =
761                                         (phdr->p_vaddr - seg->p_vaddr) +
762                                         seg->addr +
763                                         params->hdr.e_phoff - phdr->p_offset;
764                                 break;
765                         }
766                 }
767                 break;
768         }
769
770         /* determine where the dynamic section has wound up if there is one */
771         phdr = params->phdrs;
772         for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
773                 if (phdr->p_type != PT_DYNAMIC)
774                         continue;
775
776                 seg = loadmap->segs;
777                 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
778                         if (phdr->p_vaddr >= seg->p_vaddr &&
779                             phdr->p_vaddr + phdr->p_memsz <=
780                             seg->p_vaddr + seg->p_memsz) {
781                                 params->dynamic_addr =
782                                         (phdr->p_vaddr - seg->p_vaddr) +
783                                         seg->addr;
784
785                                 /* check the dynamic section contains at least
786                                  * one item, and that the last item is a NULL
787                                  * entry */
788                                 if (phdr->p_memsz == 0 ||
789                                     phdr->p_memsz % sizeof(Elf32_Dyn) != 0)
790                                         goto dynamic_error;
791
792                                 tmp = phdr->p_memsz / sizeof(Elf32_Dyn);
793                                 if (((Elf32_Dyn *)
794                                      params->dynamic_addr)[tmp - 1].d_tag != 0)
795                                         goto dynamic_error;
796                                 break;
797                         }
798                 }
799                 break;
800         }
801
802         /* now elide adjacent segments in the load map on MMU linux
803          * - on uClinux the holes between may actually be filled with system
804          *   stuff or stuff from other processes
805          */
806 #ifdef CONFIG_MMU
807         nloads = loadmap->nsegs;
808         mseg = loadmap->segs;
809         seg = mseg + 1;
810         for (loop = 1; loop < nloads; loop++) {
811                 /* see if we have a candidate for merging */
812                 if (seg->p_vaddr - mseg->p_vaddr == seg->addr - mseg->addr) {
813                         load_addr = PAGE_ALIGN(mseg->addr + mseg->p_memsz);
814                         if (load_addr == (seg->addr & PAGE_MASK)) {
815                                 mseg->p_memsz +=
816                                         load_addr -
817                                         (mseg->addr + mseg->p_memsz);
818                                 mseg->p_memsz += seg->addr & ~PAGE_MASK;
819                                 mseg->p_memsz += seg->p_memsz;
820                                 loadmap->nsegs--;
821                                 continue;
822                         }
823                 }
824
825                 mseg++;
826                 if (mseg != seg)
827                         *mseg = *seg;
828         }
829 #endif
830
831         kdebug("Mapped Object [%s]:", what);
832         kdebug("- elfhdr   : %lx", params->elfhdr_addr);
833         kdebug("- entry    : %lx", params->entry_addr);
834         kdebug("- PHDR[]   : %lx", params->ph_addr);
835         kdebug("- DYNAMIC[]: %lx", params->dynamic_addr);
836         seg = loadmap->segs;
837         for (loop = 0; loop < loadmap->nsegs; loop++, seg++)
838                 kdebug("- LOAD[%d] : %08x-%08x [va=%x ms=%x]",
839                        loop,
840                        seg->addr, seg->addr + seg->p_memsz - 1,
841                        seg->p_vaddr, seg->p_memsz);
842
843         return 0;
844
845 dynamic_error:
846         printk("ELF FDPIC %s with invalid DYNAMIC section (inode=%lu)\n",
847                what, file->f_dentry->d_inode->i_ino);
848         return -ELIBBAD;
849 }
850
851 /*****************************************************************************/
852 /*
853  * map a file with constant displacement under uClinux
854  */
855 #ifndef CONFIG_MMU
856 static int elf_fdpic_map_file_constdisp_on_uclinux(
857         struct elf_fdpic_params *params,
858         struct file *file,
859         struct mm_struct *mm)
860 {
861         struct elf32_fdpic_loadseg *seg;
862         struct elf32_phdr *phdr;
863         unsigned long load_addr, base = ULONG_MAX, top = 0, maddr = 0, mflags;
864         loff_t fpos;
865         int loop, ret;
866
867         load_addr = params->load_addr;
868         seg = params->loadmap->segs;
869
870         /* determine the bounds of the contiguous overall allocation we must
871          * make */
872         phdr = params->phdrs;
873         for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
874                 if (params->phdrs[loop].p_type != PT_LOAD)
875                         continue;
876
877                 if (base > phdr->p_vaddr)
878                         base = phdr->p_vaddr;
879                 if (top < phdr->p_vaddr + phdr->p_memsz)
880                         top = phdr->p_vaddr + phdr->p_memsz;
881         }
882
883         /* allocate one big anon block for everything */
884         mflags = MAP_PRIVATE;
885         if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
886                 mflags |= MAP_EXECUTABLE;
887
888         down_write(&mm->mmap_sem);
889         maddr = do_mmap(NULL, load_addr, top - base,
890                         PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
891         up_write(&mm->mmap_sem);
892         if (IS_ERR_VALUE(maddr))
893                 return (int) maddr;
894
895         if (load_addr != 0)
896                 load_addr += PAGE_ALIGN(top - base);
897
898         /* and then load the file segments into it */
899         phdr = params->phdrs;
900         for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
901                 if (params->phdrs[loop].p_type != PT_LOAD)
902                         continue;
903
904                 fpos = phdr->p_offset;
905
906                 seg->addr = maddr + (phdr->p_vaddr - base);
907                 seg->p_vaddr = phdr->p_vaddr;
908                 seg->p_memsz = phdr->p_memsz;
909
910                 ret = file->f_op->read(file, (void *) seg->addr,
911                                        phdr->p_filesz, &fpos);
912                 if (ret < 0)
913                         return ret;
914
915                 /* map the ELF header address if in this segment */
916                 if (phdr->p_offset == 0)
917                         params->elfhdr_addr = seg->addr;
918
919                 /* clear any space allocated but not loaded */
920                 if (phdr->p_filesz < phdr->p_memsz)
921                         clear_user((void *) (seg->addr + phdr->p_filesz),
922                                    phdr->p_memsz - phdr->p_filesz);
923
924                 if (mm) {
925                         if (phdr->p_flags & PF_X) {
926                                 mm->start_code = seg->addr;
927                                 mm->end_code = seg->addr + phdr->p_memsz;
928                         } else if (!mm->start_data) {
929                                 mm->start_data = seg->addr;
930 #ifndef CONFIG_MMU
931                                 mm->end_data = seg->addr + phdr->p_memsz;
932 #endif
933                         }
934
935 #ifdef CONFIG_MMU
936                         if (seg->addr + phdr->p_memsz > mm->end_data)
937                                 mm->end_data = seg->addr + phdr->p_memsz;
938 #endif
939                 }
940
941                 seg++;
942         }
943
944         return 0;
945 }
946 #endif
947
948 /*****************************************************************************/
949 /*
950  * map a binary by direct mmap() of the individual PT_LOAD segments
951  */
952 static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
953                                              struct file *file,
954                                              struct mm_struct *mm)
955 {
956         struct elf32_fdpic_loadseg *seg;
957         struct elf32_phdr *phdr;
958         unsigned long load_addr, delta_vaddr;
959         int loop, dvset;
960
961         load_addr = params->load_addr;
962         delta_vaddr = 0;
963         dvset = 0;
964
965         seg = params->loadmap->segs;
966
967         /* deal with each load segment separately */
968         phdr = params->phdrs;
969         for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
970                 unsigned long maddr, disp, excess, excess1;
971                 int prot = 0, flags;
972
973                 if (phdr->p_type != PT_LOAD)
974                         continue;
975
976                 kdebug("[LOAD] va=%lx of=%lx fs=%lx ms=%lx",
977                        (unsigned long) phdr->p_vaddr,
978                        (unsigned long) phdr->p_offset,
979                        (unsigned long) phdr->p_filesz,
980                        (unsigned long) phdr->p_memsz);
981
982                 /* determine the mapping parameters */
983                 if (phdr->p_flags & PF_R) prot |= PROT_READ;
984                 if (phdr->p_flags & PF_W) prot |= PROT_WRITE;
985                 if (phdr->p_flags & PF_X) prot |= PROT_EXEC;
986
987                 flags = MAP_PRIVATE | MAP_DENYWRITE;
988                 if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE)
989                         flags |= MAP_EXECUTABLE;
990
991                 maddr = 0;
992
993                 switch (params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) {
994                 case ELF_FDPIC_FLAG_INDEPENDENT:
995                         /* PT_LOADs are independently locatable */
996                         break;
997
998                 case ELF_FDPIC_FLAG_HONOURVADDR:
999                         /* the specified virtual address must be honoured */
1000                         maddr = phdr->p_vaddr;
1001                         flags |= MAP_FIXED;
1002                         break;
1003
1004                 case ELF_FDPIC_FLAG_CONSTDISP:
1005                         /* constant displacement
1006                          * - can be mapped anywhere, but must be mapped as a
1007                          *   unit
1008                          */
1009                         if (!dvset) {
1010                                 maddr = load_addr;
1011                                 delta_vaddr = phdr->p_vaddr;
1012                                 dvset = 1;
1013                         } else {
1014                                 maddr = load_addr + phdr->p_vaddr - delta_vaddr;
1015                                 flags |= MAP_FIXED;
1016                         }
1017                         break;
1018
1019                 case ELF_FDPIC_FLAG_CONTIGUOUS:
1020                         /* contiguity handled later */
1021                         break;
1022
1023                 default:
1024                         BUG();
1025                 }
1026
1027                 maddr &= PAGE_MASK;
1028
1029                 /* create the mapping */
1030                 disp = phdr->p_vaddr & ~PAGE_MASK;
1031                 down_write(&mm->mmap_sem);
1032                 maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags,
1033                                 phdr->p_offset - disp);
1034                 up_write(&mm->mmap_sem);
1035
1036                 kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
1037                        loop, phdr->p_memsz + disp, prot, flags,
1038                        phdr->p_offset - disp, maddr);
1039
1040                 if (IS_ERR_VALUE(maddr))
1041                         return (int) maddr;
1042
1043                 if ((params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) ==
1044                     ELF_FDPIC_FLAG_CONTIGUOUS)
1045                         load_addr += PAGE_ALIGN(phdr->p_memsz + disp);
1046
1047                 seg->addr = maddr + disp;
1048                 seg->p_vaddr = phdr->p_vaddr;
1049                 seg->p_memsz = phdr->p_memsz;
1050
1051                 /* map the ELF header address if in this segment */
1052                 if (phdr->p_offset == 0)
1053                         params->elfhdr_addr = seg->addr;
1054
1055                 /* clear the bit between beginning of mapping and beginning of
1056                  * PT_LOAD */
1057                 if (prot & PROT_WRITE && disp > 0) {
1058                         kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp);
1059                         clear_user((void __user *) maddr, disp);
1060                         maddr += disp;
1061                 }
1062
1063                 /* clear any space allocated but not loaded
1064                  * - on uClinux we can just clear the lot
1065                  * - on MMU linux we'll get a SIGBUS beyond the last page
1066                  *   extant in the file
1067                  */
1068                 excess = phdr->p_memsz - phdr->p_filesz;
1069                 excess1 = PAGE_SIZE - ((maddr + phdr->p_filesz) & ~PAGE_MASK);
1070
1071 #ifdef CONFIG_MMU
1072                 if (excess > excess1) {
1073                         unsigned long xaddr = maddr + phdr->p_filesz + excess1;
1074                         unsigned long xmaddr;
1075
1076                         flags |= MAP_FIXED | MAP_ANONYMOUS;
1077                         down_write(&mm->mmap_sem);
1078                         xmaddr = do_mmap(NULL, xaddr, excess - excess1,
1079                                          prot, flags, 0);
1080                         up_write(&mm->mmap_sem);
1081
1082                         kdebug("mmap[%d] <anon>"
1083                                " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
1084                                loop, xaddr, excess - excess1, prot, flags,
1085                                xmaddr);
1086
1087                         if (xmaddr != xaddr)
1088                                 return -ENOMEM;
1089                 }
1090
1091                 if (prot & PROT_WRITE && excess1 > 0) {
1092                         kdebug("clear[%d] ad=%lx sz=%lx",
1093                                loop, maddr + phdr->p_filesz, excess1);
1094                         clear_user((void __user *) maddr + phdr->p_filesz,
1095                                    excess1);
1096                 }
1097
1098 #else
1099                 if (excess > 0) {
1100                         kdebug("clear[%d] ad=%lx sz=%lx",
1101                                loop, maddr + phdr->p_filesz, excess);
1102                         clear_user((void *) maddr + phdr->p_filesz, excess);
1103                 }
1104 #endif
1105
1106                 if (mm) {
1107                         if (phdr->p_flags & PF_X) {
1108                                 mm->start_code = maddr;
1109                                 mm->end_code = maddr + phdr->p_memsz;
1110                         } else if (!mm->start_data) {
1111                                 mm->start_data = maddr;
1112                                 mm->end_data = maddr + phdr->p_memsz;
1113                         }
1114                 }
1115
1116                 seg++;
1117         }
1118
1119         return 0;
1120 }