imgact_elf.c (22d4b0fb418e0896f158ce3994ff117a708d7a7c) | imgact_elf.c (8c64af4f750d8c5fdc217c194d0d3ab5651617c3) |
---|---|
1/*- 2 * Copyright (c) 1995-1996 S�ren Schmidt 3 * Copyright (c) 1996 Peter Wemm 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * | 1/*- 2 * Copyright (c) 1995-1996 S�ren Schmidt 3 * Copyright (c) 1996 Peter Wemm 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * |
29 * $Id: imgact_elf.c,v 1.29 1998/07/29 18:39:35 dfr Exp $ | 29 * $Id: imgact_elf.c,v 1.30 1998/09/14 05:36:49 jdp Exp $ |
30 */ 31 32#include "opt_rlimit.h" 33 34#include <sys/param.h> | 30 */ 31 32#include "opt_rlimit.h" 33 34#include <sys/param.h> |
35#include <sys/systm.h> | 35#include <sys/acct.h> |
36#include <sys/exec.h> | 36#include <sys/exec.h> |
37#include <sys/mman.h> | 37#include <sys/fcntl.h> |
38#include <sys/imgact.h> 39#include <sys/imgact_elf.h> 40#include <sys/kernel.h> | 38#include <sys/imgact.h> 39#include <sys/imgact_elf.h> 40#include <sys/kernel.h> |
41#include <sys/sysent.h> | |
42#include <sys/malloc.h> | 41#include <sys/malloc.h> |
42#include <sys/mman.h> |
|
43#include <sys/namei.h> | 43#include <sys/namei.h> |
44#include <sys/pioctl.h> |
|
44#include <sys/proc.h> | 45#include <sys/proc.h> |
45#include <sys/syscall.h> | 46#include <sys/procfs.h> 47#include <sys/resourcevar.h> |
46#include <sys/signalvar.h> | 48#include <sys/signalvar.h> |
49#include <sys/stat.h> 50#include <sys/syscall.h> |
|
47#include <sys/sysctl.h> | 51#include <sys/sysctl.h> |
52#include <sys/sysent.h> 53#include <sys/systm.h> |
|
48#include <sys/vnode.h> 49 50#include <vm/vm.h> 51#include <vm/vm_kern.h> 52#include <vm/vm_param.h> 53#include <vm/pmap.h> 54#include <sys/lock.h> 55#include <vm/vm_map.h> --- 17 unchanged lines hidden (view full) --- 73#define Elf_Phdr Elf64_Phdr 74#define Elf_Auxargs Elf64_Auxargs 75#define Elf_Brandinfo Elf64_Brandinfo 76 77#endif 78 79 80static int elf_check_header __P((const Elf_Ehdr *hdr, int type)); | 54#include <sys/vnode.h> 55 56#include <vm/vm.h> 57#include <vm/vm_kern.h> 58#include <vm/vm_param.h> 59#include <vm/pmap.h> 60#include <sys/lock.h> 61#include <vm/vm_map.h> --- 17 unchanged lines hidden (view full) --- 79#define Elf_Phdr Elf64_Phdr 80#define Elf_Auxargs Elf64_Auxargs 81#define Elf_Brandinfo Elf64_Brandinfo 82 83#endif 84 85 86static int elf_check_header __P((const Elf_Ehdr *hdr, int type)); |
81static int elf_load_section __P((struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot)); 82static int elf_load_file __P((struct proc *p, char *file, u_long *addr, u_long *entry)); 83static int elf_freebsd_fixup __P((long **stack_base, struct image_params *imgp)); | 87static int elf_freebsd_fixup __P((long **stack_base, 88 struct image_params *imgp)); 89static int elf_load_file __P((struct proc *p, char *file, u_long *addr, 90 u_long *entry)); 91static int elf_load_section __P((struct vmspace *vmspace, struct vnode *vp, 92 vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, 93 vm_prot_t prot)); |
84static int exec_elf_imgact __P((struct image_params *imgp)); 85 86static int elf_trace = 0; 87SYSCTL_INT(_debug, OID_AUTO, elf_trace, CTLFLAG_RW, &elf_trace, 0, ""); 88#define UPRINTF if (elf_trace) uprintf 89 90static struct sysentvec elf_freebsd_sysvec = { 91 SYS_MAXSYSCALL, --- 542 unchanged lines hidden (view full) --- 634 635 /* don't allow modifying the file while we run it */ 636 imgp->vp->v_flag |= VTEXT; 637 638fail: 639 return error; 640} 641 | 94static int exec_elf_imgact __P((struct image_params *imgp)); 95 96static int elf_trace = 0; 97SYSCTL_INT(_debug, OID_AUTO, elf_trace, CTLFLAG_RW, &elf_trace, 0, ""); 98#define UPRINTF if (elf_trace) uprintf 99 100static struct sysentvec elf_freebsd_sysvec = { 101 SYS_MAXSYSCALL, --- 542 unchanged lines hidden (view full) --- 644 645 /* don't allow modifying the file while we run it */ 646 imgp->vp->v_flag |= VTEXT; 647 648fail: 649 return error; 650} 651 |
642int 643elf_coredump (p) 644 register struct proc *p; 645{ 646 /* Not implemented yet. */ 647 return EFAULT; 648} 649 | |
650static int 651elf_freebsd_fixup(long **stack_base, struct image_params *imgp) 652{ 653 Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; 654 long *pos; 655 656 pos = *stack_base + (imgp->argc + imgp->envc + 2); 657 --- 16 unchanged lines hidden (view full) --- 674 imgp->auxargs = NULL; 675 676 (*stack_base)--; 677 **stack_base = (long)imgp->argc; 678 return 0; 679} 680 681/* | 652static int 653elf_freebsd_fixup(long **stack_base, struct image_params *imgp) 654{ 655 Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; 656 long *pos; 657 658 pos = *stack_base + (imgp->argc + imgp->envc + 2); 659 --- 16 unchanged lines hidden (view full) --- 676 imgp->auxargs = NULL; 677 678 (*stack_base)--; 679 **stack_base = (long)imgp->argc; 680 return 0; 681} 682 683/* |
684 * Code for generating ELF core dumps. 685 */ 686 687static int elf_corehdr __P((struct proc *, struct vnode *, struct ucred *)); 688static size_t elf_hdrsize(void); 689static void elf_puthdr(void *, size_t *, const prstatus_t *, 690 const prfpregset_t *, const prpsinfo_t *, const void *, size_t, 691 const void *, size_t); 692static void elf_putnote(void *, size_t *, const char *, int, const void *, 693 size_t); 694 695extern int osreldate; 696 697int 698elf_coredump(p) 699 register struct proc *p; 700{ 701 register struct vnode *vp; 702 register struct ucred *cred = p->p_cred->pc_ucred; 703 register struct vmspace *vm = p->p_vmspace; 704 struct nameidata nd; 705 struct vattr vattr; 706 int error, error1; 707 char *name; /* name of corefile */ 708 size_t hdrsize; 709 710 STOPEVENT(p, S_CORE, 0); 711 712 if (sugid_coredump == 0 && p->p_flag & P_SUGID) 713 return (EFAULT); 714 hdrsize = elf_hdrsize(); 715 if (hdrsize + ctob(vm->vm_dsize + vm->vm_ssize) >= 716 p->p_rlimit[RLIMIT_CORE].rlim_cur) 717 return (EFAULT); 718 name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid); 719 if (name == NULL) 720 return (EFAULT); /* XXX -- not the best error */ 721 722 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p); 723 error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR); 724 free(name, M_TEMP); 725 if (error) 726 return (error); 727 vp = nd.ni_vp; 728 729 /* Don't dump to non-regular files or files with links. */ 730 if (vp->v_type != VREG || 731 VOP_GETATTR(vp, &vattr, cred, p) || vattr.va_nlink != 1) { 732 error = EFAULT; 733 goto out; 734 } 735 VATTR_NULL(&vattr); 736 vattr.va_size = 0; 737 VOP_LEASE(vp, p, cred, LEASE_WRITE); 738 VOP_SETATTR(vp, &vattr, cred, p); 739 p->p_acflag |= ACORE; 740 error = elf_corehdr(p, vp, cred); 741 if (error == 0) 742 error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr, 743 (int)ctob(vm->vm_dsize), (off_t)hdrsize, UIO_USERSPACE, 744 IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p); 745 if (error == 0) 746 error = vn_rdwr(UIO_WRITE, vp, 747 (caddr_t) trunc_page(USRSTACK - ctob(vm->vm_ssize)), 748 round_page(ctob(vm->vm_ssize)), 749 (off_t)hdrsize + ctob(vm->vm_dsize), UIO_USERSPACE, 750 IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p); 751out: 752 VOP_UNLOCK(vp, 0, p); 753 error1 = vn_close(vp, FWRITE, cred, p); 754 if (error == 0) 755 error = error1; 756 return (error); 757} 758 759static int 760elf_corehdr(p, vp, cred) 761 struct proc *p; 762 struct vnode *vp; 763 struct ucred *cred; 764{ 765 struct vmspace *vm = p->p_vmspace; 766 size_t off; 767 size_t hdrsize; 768 prstatus_t status; 769 prfpregset_t fpregset; 770 prpsinfo_t psinfo; 771 void *hdr; 772 int error; 773 774 /* Gather the information for the header. */ 775 bzero(&status, sizeof status); 776 status.pr_version = PRSTATUS_VERSION; 777 status.pr_statussz = sizeof(prstatus_t); 778 status.pr_gregsetsz = sizeof(gregset_t); 779 status.pr_fpregsetsz = sizeof(fpregset_t); 780 status.pr_osreldate = osreldate; 781 status.pr_cursig = p->p_sigacts->ps_sig; 782 status.pr_pid = p->p_pid; 783 fill_regs(p, &status.pr_reg); 784 785 fill_fpregs(p, &fpregset); 786 787 bzero(&psinfo, sizeof psinfo); 788 psinfo.pr_version = PRPSINFO_VERSION; 789 psinfo.pr_psinfosz = sizeof(prpsinfo_t); 790 strncpy(psinfo.pr_fname, p->p_comm, MAXCOMLEN); 791 psinfo.pr_psargs[0] = '\0'; /* XXX - args not implemented yet */ 792 793 /* Allocate memory for building the header. */ 794 hdrsize = elf_hdrsize(); 795 hdr = malloc(hdrsize, M_TEMP, M_WAITOK); 796 if (hdr == NULL) 797 return EINVAL; 798 bzero(hdr, hdrsize); 799 800 /* Fill in the header. */ 801 off = 0; 802 elf_puthdr(hdr, &off, &status, &fpregset, &psinfo, 803 vm->vm_daddr, ctob(vm->vm_dsize), 804 (void *)trunc_page(USRSTACK - ctob(vm->vm_ssize)), 805 ctob(vm->vm_ssize)); 806 807 /* Write it to the core file. */ 808 error = vn_rdwr(UIO_WRITE, vp, hdr, hdrsize, (off_t)0, 809 UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p); 810 811 free(hdr, M_TEMP); 812 return error; 813} 814 815static size_t 816elf_hdrsize(void) 817{ 818 size_t off; 819 820 off = 0; 821 elf_puthdr(NULL, &off, NULL, NULL, NULL, NULL, 0, NULL, 0); 822 return off; 823} 824 825static void 826elf_puthdr(void *dst, size_t *off, const prstatus_t *status, 827 const prfpregset_t *fpregset, const prpsinfo_t *psinfo, 828 const void *data, size_t datasz, const void *stack, size_t stacksz) 829{ 830 size_t ehoff; 831 size_t phoff; 832 size_t noteoff; 833 size_t notesz; 834 size_t dataoff; 835 size_t stackoff; 836 int numsegs = 3; 837 838 ehoff = *off; 839 *off += sizeof(Elf_Ehdr); 840 841 phoff = *off; 842 *off += numsegs * sizeof(Elf_Phdr); 843 844 noteoff = *off; 845 elf_putnote(dst, off, "FreeBSD", NT_PRSTATUS, status, 846 sizeof *status); 847 elf_putnote(dst, off, "FreeBSD", NT_FPREGSET, fpregset, 848 sizeof *fpregset); 849 elf_putnote(dst, off, "FreeBSD", NT_PRPSINFO, psinfo, 850 sizeof *psinfo); 851 notesz = *off - noteoff; 852 853 /* Align up to a page boundary for the data segment. */ 854 *off = round_page(*off); 855 856 if (dst != NULL) { 857 Elf_Ehdr *ehdr; 858 Elf_Phdr *phdr; 859 860 /* 861 * Fill in the ELF header. 862 */ 863 ehdr = (Elf_Ehdr *)((char *)dst + ehoff); 864 ehdr->e_ident[EI_MAG0] = ELFMAG0; 865 ehdr->e_ident[EI_MAG1] = ELFMAG1; 866 ehdr->e_ident[EI_MAG2] = ELFMAG2; 867 ehdr->e_ident[EI_MAG3] = ELFMAG3; 868 ehdr->e_ident[EI_CLASS] = ELF_CLASS; 869 ehdr->e_ident[EI_DATA] = ELF_DATA; 870 ehdr->e_ident[EI_VERSION] = EV_CURRENT; 871 ehdr->e_ident[EI_PAD] = 0; 872 strncpy(ehdr->e_ident + EI_BRAND, "FreeBSD", 873 EI_NIDENT - EI_BRAND); 874 ehdr->e_type = ET_CORE; 875 ehdr->e_machine = ELF_ARCH; 876 ehdr->e_version = EV_CURRENT; 877 ehdr->e_entry = 0; 878 ehdr->e_phoff = phoff; 879 ehdr->e_flags = 0; 880 ehdr->e_ehsize = sizeof(Elf_Ehdr); 881 ehdr->e_phentsize = sizeof(Elf_Phdr); 882 ehdr->e_phnum = numsegs; 883 ehdr->e_shentsize = sizeof(Elf_Shdr); 884 ehdr->e_shnum = 0; 885 ehdr->e_shstrndx = SHN_UNDEF; 886 887 /* 888 * Fill in the program header entries. 889 */ 890 phdr = (Elf_Phdr *)((char *)dst + phoff); 891 892 /* The note segement. */ 893 phdr->p_type = PT_NOTE; 894 phdr->p_offset = noteoff; 895 phdr->p_vaddr = 0; 896 phdr->p_paddr = 0; 897 phdr->p_filesz = notesz; 898 phdr->p_memsz = 0; 899 phdr->p_flags = 0; 900 phdr->p_align = 0; 901 phdr++; 902 903 /* The data segment. */ 904 phdr->p_type = PT_LOAD; 905 phdr->p_offset = *off; 906 phdr->p_vaddr = (Elf_Addr)data; 907 phdr->p_paddr = 0; 908 phdr->p_filesz = phdr->p_memsz = datasz; 909 phdr->p_align = PAGE_SIZE; 910 phdr->p_flags = PF_R | PF_W | PF_X; 911 phdr++; 912 913 /* The stack segment. */ 914 phdr->p_type = PT_LOAD; 915 phdr->p_offset = *off + datasz; 916 phdr->p_vaddr = (Elf_Addr)stack; 917 phdr->p_paddr = 0; 918 phdr->p_filesz = phdr->p_memsz = stacksz; 919 phdr->p_align = PAGE_SIZE; 920 phdr->p_flags = PF_R | PF_W | PF_X; 921 phdr++; 922 } 923} 924 925static void 926elf_putnote(void *dst, size_t *off, const char *name, int type, 927 const void *desc, size_t descsz) 928{ 929 Elf_Note note; 930 931 note.n_namesz = strlen(name) + 1; 932 note.n_descsz = descsz; 933 note.n_type = type; 934 if (dst != NULL) 935 bcopy(¬e, (char *)dst + *off, sizeof note); 936 *off += sizeof note; 937 if (dst != NULL) 938 bcopy(name, (char *)dst + *off, note.n_namesz); 939 *off += roundup2(note.n_namesz, sizeof(Elf_Size)); 940 if (dst != NULL) 941 bcopy(desc, (char *)dst + *off, note.n_descsz); 942 *off += roundup2(note.n_descsz, sizeof(Elf_Size)); 943} 944 945/* |
|
682 * Tell kern_execve.c about it, with a little help from the linker. 683 * Since `const' objects end up in the text segment, TEXT_SET is the 684 * correct directive to use. 685 */ 686static const struct execsw elf_execsw = {exec_elf_imgact, "ELF"}; 687TEXT_SET(execsw_set, elf_execsw); 688 | 946 * Tell kern_execve.c about it, with a little help from the linker. 947 * Since `const' objects end up in the text segment, TEXT_SET is the 948 * correct directive to use. 949 */ 950static const struct execsw elf_execsw = {exec_elf_imgact, "ELF"}; 951TEXT_SET(execsw_set, elf_execsw); 952 |