Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 768cbfbc5273bad91afe12b81471f563b288118a 550 lines 15 kB view raw
1/* 2 * linux/fs/binfmt_aout.c 3 * 4 * Copyright (C) 1991, 1992, 1996 Linus Torvalds 5 */ 6 7#include <linux/module.h> 8 9#include <linux/time.h> 10#include <linux/kernel.h> 11#include <linux/mm.h> 12#include <linux/mman.h> 13#include <linux/a.out.h> 14#include <linux/errno.h> 15#include <linux/signal.h> 16#include <linux/string.h> 17#include <linux/fs.h> 18#include <linux/file.h> 19#include <linux/stat.h> 20#include <linux/fcntl.h> 21#include <linux/ptrace.h> 22#include <linux/user.h> 23#include <linux/slab.h> 24#include <linux/binfmts.h> 25#include <linux/personality.h> 26#include <linux/init.h> 27 28#include <asm/system.h> 29#include <asm/uaccess.h> 30#include <asm/cacheflush.h> 31 32static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); 33static int load_aout_library(struct file*); 34static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file); 35 36extern void dump_thread(struct pt_regs *, struct user *); 37 38static struct linux_binfmt aout_format = { 39 .module = THIS_MODULE, 40 .load_binary = load_aout_binary, 41 .load_shlib = load_aout_library, 42 .core_dump = aout_core_dump, 43 .min_coredump = PAGE_SIZE 44}; 45 46#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) 47 48static int set_brk(unsigned long start, unsigned long end) 49{ 50 start = PAGE_ALIGN(start); 51 end = PAGE_ALIGN(end); 52 if (end > start) { 53 unsigned long addr; 54 down_write(&current->mm->mmap_sem); 55 addr = do_brk(start, end - start); 56 up_write(&current->mm->mmap_sem); 57 if (BAD_ADDR(addr)) 58 return addr; 59 } 60 return 0; 61} 62 63/* 64 * These are the only things you should do on a core-file: use only these 65 * macros to write out all the necessary info. 66 */ 67 68static int dump_write(struct file *file, const void *addr, int nr) 69{ 70 return file->f_op->write(file, addr, nr, &file->f_pos) == nr; 71} 72 73#define DUMP_WRITE(addr, nr) \ 74 if (!dump_write(file, (void *)(addr), (nr))) \ 75 goto end_coredump; 76 77#define DUMP_SEEK(offset) \ 78if (file->f_op->llseek) { \ 79 if (file->f_op->llseek(file,(offset),0) != (offset)) \ 80 goto end_coredump; \ 81} else file->f_pos = (offset) 82 83/* 84 * Routine writes a core dump image in the current directory. 85 * Currently only a stub-function. 86 * 87 * Note that setuid/setgid files won't make a core-dump if the uid/gid 88 * changed due to the set[u|g]id. It's enforced by the "current->mm->dumpable" 89 * field, which also makes sure the core-dumps won't be recursive if the 90 * dumping of the process results in another error.. 91 */ 92 93static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file) 94{ 95 mm_segment_t fs; 96 int has_dumped = 0; 97 unsigned long dump_start, dump_size; 98 struct user dump; 99#if defined(__alpha__) 100# define START_DATA(u) (u.start_data) 101#elif defined(__arm__) 102# define START_DATA(u) ((u.u_tsize << PAGE_SHIFT) + u.start_code) 103#elif defined(__sparc__) 104# define START_DATA(u) (u.u_tsize) 105#elif defined(__i386__) || defined(__mc68000__) || defined(__arch_um__) 106# define START_DATA(u) (u.u_tsize << PAGE_SHIFT) 107#endif 108#ifdef __sparc__ 109# define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1)) 110#else 111# define START_STACK(u) (u.start_stack) 112#endif 113 114 fs = get_fs(); 115 set_fs(KERNEL_DS); 116 has_dumped = 1; 117 current->flags |= PF_DUMPCORE; 118 strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); 119#ifndef __sparc__ 120 dump.u_ar0 = (void *)(((unsigned long)(&dump.regs)) - ((unsigned long)(&dump))); 121#endif 122 dump.signal = signr; 123 dump_thread(regs, &dump); 124 125/* If the size of the dump file exceeds the rlimit, then see what would happen 126 if we wrote the stack, but not the data area. */ 127#ifdef __sparc__ 128 if ((dump.u_dsize+dump.u_ssize) > 129 current->signal->rlim[RLIMIT_CORE].rlim_cur) 130 dump.u_dsize = 0; 131#else 132 if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE > 133 current->signal->rlim[RLIMIT_CORE].rlim_cur) 134 dump.u_dsize = 0; 135#endif 136 137/* Make sure we have enough room to write the stack and data areas. */ 138#ifdef __sparc__ 139 if ((dump.u_ssize) > 140 current->signal->rlim[RLIMIT_CORE].rlim_cur) 141 dump.u_ssize = 0; 142#else 143 if ((dump.u_ssize+1) * PAGE_SIZE > 144 current->signal->rlim[RLIMIT_CORE].rlim_cur) 145 dump.u_ssize = 0; 146#endif 147 148/* make sure we actually have a data and stack area to dump */ 149 set_fs(USER_DS); 150#ifdef __sparc__ 151 if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize)) 152 dump.u_dsize = 0; 153 if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize)) 154 dump.u_ssize = 0; 155#else 156 if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) 157 dump.u_dsize = 0; 158 if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) 159 dump.u_ssize = 0; 160#endif 161 162 set_fs(KERNEL_DS); 163/* struct user */ 164 DUMP_WRITE(&dump,sizeof(dump)); 165/* Now dump all of the user data. Include malloced stuff as well */ 166#ifndef __sparc__ 167 DUMP_SEEK(PAGE_SIZE); 168#endif 169/* now we start writing out the user space info */ 170 set_fs(USER_DS); 171/* Dump the data area */ 172 if (dump.u_dsize != 0) { 173 dump_start = START_DATA(dump); 174#ifdef __sparc__ 175 dump_size = dump.u_dsize; 176#else 177 dump_size = dump.u_dsize << PAGE_SHIFT; 178#endif 179 DUMP_WRITE(dump_start,dump_size); 180 } 181/* Now prepare to dump the stack area */ 182 if (dump.u_ssize != 0) { 183 dump_start = START_STACK(dump); 184#ifdef __sparc__ 185 dump_size = dump.u_ssize; 186#else 187 dump_size = dump.u_ssize << PAGE_SHIFT; 188#endif 189 DUMP_WRITE(dump_start,dump_size); 190 } 191/* Finally dump the task struct. Not be used by gdb, but could be useful */ 192 set_fs(KERNEL_DS); 193 DUMP_WRITE(current,sizeof(*current)); 194end_coredump: 195 set_fs(fs); 196 return has_dumped; 197} 198 199/* 200 * create_aout_tables() parses the env- and arg-strings in new user 201 * memory and creates the pointer tables from them, and puts their 202 * addresses on the "stack", returning the new stack pointer value. 203 */ 204static unsigned long __user *create_aout_tables(char __user *p, struct linux_binprm * bprm) 205{ 206 char __user * __user *argv; 207 char __user * __user *envp; 208 unsigned long __user *sp; 209 int argc = bprm->argc; 210 int envc = bprm->envc; 211 212 sp = (void __user *)((-(unsigned long)sizeof(char *)) & (unsigned long) p); 213#ifdef __sparc__ 214 /* This imposes the proper stack alignment for a new process. */ 215 sp = (void __user *) (((unsigned long) sp) & ~7); 216 if ((envc+argc+3)&1) --sp; 217#endif 218#ifdef __alpha__ 219/* whee.. test-programs are so much fun. */ 220 put_user(0, --sp); 221 put_user(0, --sp); 222 if (bprm->loader) { 223 put_user(0, --sp); 224 put_user(0x3eb, --sp); 225 put_user(bprm->loader, --sp); 226 put_user(0x3ea, --sp); 227 } 228 put_user(bprm->exec, --sp); 229 put_user(0x3e9, --sp); 230#endif 231 sp -= envc+1; 232 envp = (char __user * __user *) sp; 233 sp -= argc+1; 234 argv = (char __user * __user *) sp; 235#if defined(__i386__) || defined(__mc68000__) || defined(__arm__) || defined(__arch_um__) 236 put_user((unsigned long) envp,--sp); 237 put_user((unsigned long) argv,--sp); 238#endif 239 put_user(argc,--sp); 240 current->mm->arg_start = (unsigned long) p; 241 while (argc-->0) { 242 char c; 243 put_user(p,argv++); 244 do { 245 get_user(c,p++); 246 } while (c); 247 } 248 put_user(NULL,argv); 249 current->mm->arg_end = current->mm->env_start = (unsigned long) p; 250 while (envc-->0) { 251 char c; 252 put_user(p,envp++); 253 do { 254 get_user(c,p++); 255 } while (c); 256 } 257 put_user(NULL,envp); 258 current->mm->env_end = (unsigned long) p; 259 return sp; 260} 261 262/* 263 * These are the functions used to load a.out style executables and shared 264 * libraries. There is no binary dependent code anywhere else. 265 */ 266 267static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) 268{ 269 struct exec ex; 270 unsigned long error; 271 unsigned long fd_offset; 272 unsigned long rlim; 273 int retval; 274 275 ex = *((struct exec *) bprm->buf); /* exec-header */ 276 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 277 N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || 278 N_TRSIZE(ex) || N_DRSIZE(ex) || 279 i_size_read(bprm->file->f_dentry->d_inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { 280 return -ENOEXEC; 281 } 282 283 fd_offset = N_TXTOFF(ex); 284 285 /* Check initial limits. This avoids letting people circumvent 286 * size limits imposed on them by creating programs with large 287 * arrays in the data or bss. 288 */ 289 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; 290 if (rlim >= RLIM_INFINITY) 291 rlim = ~0; 292 if (ex.a_data + ex.a_bss > rlim) 293 return -ENOMEM; 294 295 /* Flush all traces of the currently running executable */ 296 retval = flush_old_exec(bprm); 297 if (retval) 298 return retval; 299 300 /* OK, This is the point of no return */ 301#if defined(__alpha__) 302 SET_AOUT_PERSONALITY(bprm, ex); 303#elif defined(__sparc__) 304 set_personality(PER_SUNOS); 305#if !defined(__sparc_v9__) 306 memcpy(&current->thread.core_exec, &ex, sizeof(struct exec)); 307#endif 308#else 309 set_personality(PER_LINUX); 310#endif 311 312 current->mm->end_code = ex.a_text + 313 (current->mm->start_code = N_TXTADDR(ex)); 314 current->mm->end_data = ex.a_data + 315 (current->mm->start_data = N_DATADDR(ex)); 316 current->mm->brk = ex.a_bss + 317 (current->mm->start_brk = N_BSSADDR(ex)); 318 current->mm->free_area_cache = current->mm->mmap_base; 319 320 set_mm_counter(current->mm, rss, 0); 321 current->mm->mmap = NULL; 322 compute_creds(bprm); 323 current->flags &= ~PF_FORKNOEXEC; 324#ifdef __sparc__ 325 if (N_MAGIC(ex) == NMAGIC) { 326 loff_t pos = fd_offset; 327 /* Fuck me plenty... */ 328 /* <AOL></AOL> */ 329 down_write(&current->mm->mmap_sem); 330 error = do_brk(N_TXTADDR(ex), ex.a_text); 331 up_write(&current->mm->mmap_sem); 332 bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex), 333 ex.a_text, &pos); 334 down_write(&current->mm->mmap_sem); 335 error = do_brk(N_DATADDR(ex), ex.a_data); 336 up_write(&current->mm->mmap_sem); 337 bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex), 338 ex.a_data, &pos); 339 goto beyond_if; 340 } 341#endif 342 343 if (N_MAGIC(ex) == OMAGIC) { 344 unsigned long text_addr, map_size; 345 loff_t pos; 346 347 text_addr = N_TXTADDR(ex); 348 349#if defined(__alpha__) || defined(__sparc__) 350 pos = fd_offset; 351 map_size = ex.a_text+ex.a_data + PAGE_SIZE - 1; 352#else 353 pos = 32; 354 map_size = ex.a_text+ex.a_data; 355#endif 356 down_write(&current->mm->mmap_sem); 357 error = do_brk(text_addr & PAGE_MASK, map_size); 358 up_write(&current->mm->mmap_sem); 359 if (error != (text_addr & PAGE_MASK)) { 360 send_sig(SIGKILL, current, 0); 361 return error; 362 } 363 364 error = bprm->file->f_op->read(bprm->file, 365 (char __user *)text_addr, 366 ex.a_text+ex.a_data, &pos); 367 if ((signed long)error < 0) { 368 send_sig(SIGKILL, current, 0); 369 return error; 370 } 371 372 flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data); 373 } else { 374 static unsigned long error_time, error_time2; 375 if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && 376 (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time2) > 5*HZ) 377 { 378 printk(KERN_NOTICE "executable not page aligned\n"); 379 error_time2 = jiffies; 380 } 381 382 if ((fd_offset & ~PAGE_MASK) != 0 && 383 (jiffies-error_time) > 5*HZ) 384 { 385 printk(KERN_WARNING 386 "fd_offset is not page aligned. Please convert program: %s\n", 387 bprm->file->f_dentry->d_name.name); 388 error_time = jiffies; 389 } 390 391 if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { 392 loff_t pos = fd_offset; 393 down_write(&current->mm->mmap_sem); 394 do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); 395 up_write(&current->mm->mmap_sem); 396 bprm->file->f_op->read(bprm->file, 397 (char __user *)N_TXTADDR(ex), 398 ex.a_text+ex.a_data, &pos); 399 flush_icache_range((unsigned long) N_TXTADDR(ex), 400 (unsigned long) N_TXTADDR(ex) + 401 ex.a_text+ex.a_data); 402 goto beyond_if; 403 } 404 405 down_write(&current->mm->mmap_sem); 406 error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, 407 PROT_READ | PROT_EXEC, 408 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, 409 fd_offset); 410 up_write(&current->mm->mmap_sem); 411 412 if (error != N_TXTADDR(ex)) { 413 send_sig(SIGKILL, current, 0); 414 return error; 415 } 416 417 down_write(&current->mm->mmap_sem); 418 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, 419 PROT_READ | PROT_WRITE | PROT_EXEC, 420 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, 421 fd_offset + ex.a_text); 422 up_write(&current->mm->mmap_sem); 423 if (error != N_DATADDR(ex)) { 424 send_sig(SIGKILL, current, 0); 425 return error; 426 } 427 } 428beyond_if: 429 set_binfmt(&aout_format); 430 431 retval = set_brk(current->mm->start_brk, current->mm->brk); 432 if (retval < 0) { 433 send_sig(SIGKILL, current, 0); 434 return retval; 435 } 436 437 retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); 438 if (retval < 0) { 439 /* Someone check-me: is this error path enough? */ 440 send_sig(SIGKILL, current, 0); 441 return retval; 442 } 443 444 current->mm->start_stack = 445 (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); 446#ifdef __alpha__ 447 regs->gp = ex.a_gpvalue; 448#endif 449 start_thread(regs, ex.a_entry, current->mm->start_stack); 450 if (unlikely(current->ptrace & PT_PTRACED)) { 451 if (current->ptrace & PT_TRACE_EXEC) 452 ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP); 453 else 454 send_sig(SIGTRAP, current, 0); 455 } 456 return 0; 457} 458 459static int load_aout_library(struct file *file) 460{ 461 struct inode * inode; 462 unsigned long bss, start_addr, len; 463 unsigned long error; 464 int retval; 465 struct exec ex; 466 467 inode = file->f_dentry->d_inode; 468 469 retval = -ENOEXEC; 470 error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); 471 if (error != sizeof(ex)) 472 goto out; 473 474 /* We come in here for the regular a.out style of shared libraries */ 475 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) || 476 N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) || 477 i_size_read(inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { 478 goto out; 479 } 480 481 if (N_FLAGS(ex)) 482 goto out; 483 484 /* For QMAGIC, the starting address is 0x20 into the page. We mask 485 this off to get the starting address for the page */ 486 487 start_addr = ex.a_entry & 0xfffff000; 488 489 if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) { 490 static unsigned long error_time; 491 loff_t pos = N_TXTOFF(ex); 492 493 if ((jiffies-error_time) > 5*HZ) 494 { 495 printk(KERN_WARNING 496 "N_TXTOFF is not page aligned. Please convert library: %s\n", 497 file->f_dentry->d_name.name); 498 error_time = jiffies; 499 } 500 down_write(&current->mm->mmap_sem); 501 do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); 502 up_write(&current->mm->mmap_sem); 503 504 file->f_op->read(file, (char __user *)start_addr, 505 ex.a_text + ex.a_data, &pos); 506 flush_icache_range((unsigned long) start_addr, 507 (unsigned long) start_addr + ex.a_text + ex.a_data); 508 509 retval = 0; 510 goto out; 511 } 512 /* Now use mmap to map the library into memory. */ 513 down_write(&current->mm->mmap_sem); 514 error = do_mmap(file, start_addr, ex.a_text + ex.a_data, 515 PROT_READ | PROT_WRITE | PROT_EXEC, 516 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, 517 N_TXTOFF(ex)); 518 up_write(&current->mm->mmap_sem); 519 retval = error; 520 if (error != start_addr) 521 goto out; 522 523 len = PAGE_ALIGN(ex.a_text + ex.a_data); 524 bss = ex.a_text + ex.a_data + ex.a_bss; 525 if (bss > len) { 526 down_write(&current->mm->mmap_sem); 527 error = do_brk(start_addr + len, bss - len); 528 up_write(&current->mm->mmap_sem); 529 retval = error; 530 if (error != start_addr + len) 531 goto out; 532 } 533 retval = 0; 534out: 535 return retval; 536} 537 538static int __init init_aout_binfmt(void) 539{ 540 return register_binfmt(&aout_format); 541} 542 543static void __exit exit_aout_binfmt(void) 544{ 545 unregister_binfmt(&aout_format); 546} 547 548core_initcall(init_aout_binfmt); 549module_exit(exit_aout_binfmt); 550MODULE_LICENSE("GPL");