/* * linux/fs/exec.c * * Copyright (C) 1991, 1992 Linus Torvalds *//* * #!-checking implemented by tytso. *//* * Demand-loading implemented 01.12.91 - no need to read anything but * the header into memory. The inode of the executable is put into * "current->executable", and page faults do the actual loading. Clean. * * Once more I can proudly say that linux stood up to being changed: it * was less than 2 hours work to get demand-loading completely implemented. * * Demand loading changed July 1993 by Eric Youngdale. Use mmap instead, * current->executable is only used by the procfs. This allows a dispatch * table to check for several different types of binary formats. We keep * trying until we recognize the file or we run out of supported binary * formats. */#include <linux/config.h>#include <linux/slab.h>#include <linux/file.h>#include <linux/mman.h>#include <linux/a.out.h>#include <linux/stat.h>#include <linux/fcntl.h>#include <linux/smp_lock.h>#include <linux/init.h>#include <linux/pagemap.h>#include <linux/highmem.h>#include <linux/spinlock.h>#include <linux/key.h>#include <linux/personality.h>#include <linux/binfmts.h>#include <linux/swap.h>#include <linux/utsname.h>#include <linux/module.h>#include <linux/namei.h>#include <linux/proc_fs.h>#include <linux/ptrace.h>#include <linux/mount.h>#include <linux/security.h>#include <linux/syscalls.h>#include <linux/rmap.h>#include <linux/acct.h>#include <linux/cn_proc.h>#include <asm/uaccess.h>#include <asm/mmu_context.h>#ifdef CONFIG_KMOD#include <linux/kmod.h>#endifint core_uses_pid;char core_pattern[65] ="core";int suid_dumpable =0;EXPORT_SYMBOL(suid_dumpable);/* The maximal length of core_pattern is also specified in sysctl.c */static struct linux_binfmt *formats;staticDEFINE_RWLOCK(binfmt_lock);intregister_binfmt(struct linux_binfmt * fmt){struct linux_binfmt ** tmp = &formats;if(!fmt)return-EINVAL;if(fmt->next)return-EBUSY;write_lock(&binfmt_lock);while(*tmp) {if(fmt == *tmp) {write_unlock(&binfmt_lock);return-EBUSY;}
tmp = &(*tmp)->next;}
fmt->next = formats;
formats = fmt;write_unlock(&binfmt_lock);return0;}EXPORT_SYMBOL(register_binfmt);intunregister_binfmt(struct linux_binfmt * fmt){struct linux_binfmt ** tmp = &formats;write_lock(&binfmt_lock);while(*tmp) {if(fmt == *tmp) {*tmp = fmt->next;write_unlock(&binfmt_lock);return0;}
tmp = &(*tmp)->next;}write_unlock(&binfmt_lock);return-EINVAL;}EXPORT_SYMBOL(unregister_binfmt);staticinlinevoidput_binfmt(struct linux_binfmt * fmt){module_put(