The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/linux/linux_sysvec.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1994-1996 Søren Schmidt
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer 
   10  *    in this position and unchanged.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software withough specific prior written permission
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * $FreeBSD$
   29  */
   30 
   31 /* XXX we use functions that might not exist. */
   32 #include "opt_compat.h"
   33 
   34 #ifndef COMPAT_43
   35 #error "Unable to compile Linux-emulator due to missing COMPAT_43 option!"
   36 #endif
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/imgact.h>
   41 #include <sys/imgact_aout.h>
   42 #include <sys/imgact_elf.h>
   43 #include <sys/lock.h>
   44 #include <sys/malloc.h>
   45 #include <sys/proc.h>
   46 #include <sys/signalvar.h>
   47 #include <sys/sysent.h>
   48 #include <sys/sysproto.h>
   49 
   50 #include <vm/vm.h>
   51 #include <vm/vm_param.h>
   52 #include <vm/vm_page.h>
   53 #include <vm/vm_extern.h>
   54 #include <sys/exec.h>
   55 #include <sys/kernel.h>
   56 #include <sys/module.h>
   57 #include <machine/cpu.h>
   58 
   59 #include <i386/linux/linux.h>
   60 #include <i386/linux/linux_proto.h>
   61 #include <compat/linux/linux_signal.h>
   62 #include <compat/linux/linux_util.h>
   63 
   64 MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
   65 
   66 #if BYTE_ORDER == LITTLE_ENDIAN
   67 #define SHELLMAGIC      0x2123 /* #! */
   68 #else
   69 #define SHELLMAGIC      0x2321
   70 #endif
   71 
   72 /*
   73  * Allow the sendsig functions to use the ldebug() facility
   74  * even though they are not syscalls themselves. Map them
   75  * to syscall 0. This is slightly less bogus than using
   76  * ldebug(sigreturn).
   77  */
   78 #define LINUX_SYS_linux_rt_sendsig      0
   79 #define LINUX_SYS_linux_sendsig         0
   80 
   81 extern char linux_sigcode[];
   82 extern int linux_szsigcode;
   83 
   84 extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
   85 
   86 extern struct linker_set linux_ioctl_handler_set;
   87 
   88 static int      linux_fixup __P((register_t **stack_base,
   89                                  struct image_params *iparams));
   90 static int      elf_linux_fixup __P((register_t **stack_base,
   91                                      struct image_params *iparams));
   92 static void     linux_prepsyscall __P((struct trapframe *tf, int *args,
   93                                        u_int *code, caddr_t *params));
   94 static void     linux_sendsig __P((sig_t catcher, int sig, sigset_t *mask,
   95                                    u_long code));
   96 
   97 /*
   98  * Linux syscalls return negative errno's, we do positive and map them
   99  */
  100 static int bsd_to_linux_errno[ELAST + 1] = {
  101         -0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
  102         -10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
  103         -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
  104         -30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
  105         -90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
  106         -100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
  107         -110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
  108         -116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
  109         -6, -6, -43, -42, -75, -6, -84
  110 };
  111 
  112 int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
  113         LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
  114         LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
  115         LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, 0,
  116         LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
  117         LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
  118         LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
  119         LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
  120         0, LINUX_SIGUSR1, LINUX_SIGUSR2
  121 };
  122 
  123 int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
  124         SIGHUP, SIGINT, SIGQUIT, SIGILL,
  125         SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
  126         SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
  127         SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
  128         SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
  129         SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
  130         SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
  131         SIGIO, SIGURG, 0
  132 };
  133 
  134 #define LINUX_T_UNKNOWN  255
  135 static int _bsd_to_linux_trapcode[] = {
  136         LINUX_T_UNKNOWN,        /* 0 */
  137         6,                      /* 1  T_PRIVINFLT */
  138         LINUX_T_UNKNOWN,        /* 2 */
  139         3,                      /* 3  T_BPTFLT */
  140         LINUX_T_UNKNOWN,        /* 4 */
  141         LINUX_T_UNKNOWN,        /* 5 */
  142         16,                     /* 6  T_ARITHTRAP */
  143         254,                    /* 7  T_ASTFLT */
  144         LINUX_T_UNKNOWN,        /* 8 */
  145         13,                     /* 9  T_PROTFLT */
  146         1,                      /* 10 T_TRCTRAP */
  147         LINUX_T_UNKNOWN,        /* 11 */
  148         14,                     /* 12 T_PAGEFLT */
  149         LINUX_T_UNKNOWN,        /* 13 */
  150         17,                     /* 14 T_ALIGNFLT */
  151         LINUX_T_UNKNOWN,        /* 15 */
  152         LINUX_T_UNKNOWN,        /* 16 */
  153         LINUX_T_UNKNOWN,        /* 17 */
  154         0,                      /* 18 T_DIVIDE */
  155         2,                      /* 19 T_NMI */
  156         4,                      /* 20 T_OFLOW */
  157         5,                      /* 21 T_BOUND */
  158         7,                      /* 22 T_DNA */
  159         8,                      /* 23 T_DOUBLEFLT */
  160         9,                      /* 24 T_FPOPFLT */
  161         10,                     /* 25 T_TSSFLT */
  162         11,                     /* 26 T_SEGNPFLT */
  163         12,                     /* 27 T_STKFLT */
  164         18,                     /* 28 T_MCHK */
  165         19,                     /* 29 T_XMMFLT */
  166         15                      /* 30 T_RESERVED */
  167 };
  168 #define bsd_to_linux_trapcode(code) \
  169     ((code)<sizeof(_bsd_to_linux_trapcode)/sizeof(*_bsd_to_linux_trapcode)? \
  170      _bsd_to_linux_trapcode[(code)]: \
  171      LINUX_T_UNKNOWN)
  172 
  173 /*
  174  * If FreeBSD & Linux have a difference of opinion about what a trap
  175  * means, deal with it here.
  176  */
  177 static int
  178 translate_traps(int signal, int trap_code)
  179 {
  180         if (signal != SIGBUS)
  181                 return signal;
  182         switch (trap_code) {
  183         case T_PROTFLT:
  184         case T_TSSFLT:
  185         case T_DOUBLEFLT:
  186         case T_PAGEFLT:
  187                 return SIGSEGV;
  188         default:
  189                 return signal;
  190         }
  191 }
  192 
  193 static int
  194 linux_fixup(register_t **stack_base, struct image_params *imgp)
  195 {
  196         register_t *argv, *envp;
  197 
  198         argv = *stack_base;
  199         envp = *stack_base + (imgp->argc + 1);
  200         (*stack_base)--;
  201         **stack_base = (intptr_t)(void *)envp;
  202         (*stack_base)--;
  203         **stack_base = (intptr_t)(void *)argv;
  204         (*stack_base)--;
  205         **stack_base = imgp->argc;
  206         return 0;
  207 }
  208 
  209 static int
  210 elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
  211 {
  212         Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs;
  213         register_t *pos;
  214              
  215         pos = *stack_base + (imgp->argc + imgp->envc + 2);  
  216     
  217         if (args->trace) {
  218                 AUXARGS_ENTRY(pos, AT_DEBUG, 1);
  219         }
  220         if (args->execfd != -1) {
  221                 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
  222         }       
  223         AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
  224         AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
  225         AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
  226         AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
  227         AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
  228         AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
  229         AUXARGS_ENTRY(pos, AT_BASE, args->base);
  230         AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid);
  231         AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid);
  232         AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid);
  233         AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid);
  234         AUXARGS_ENTRY(pos, AT_NULL, 0);
  235         
  236         free(imgp->auxargs, M_TEMP);      
  237         imgp->auxargs = NULL;
  238 
  239         (*stack_base)--;
  240         **stack_base = (long)imgp->argc;
  241         return 0;
  242 }
  243 
  244 extern int _ucodesel, _udatasel;
  245 extern unsigned long linux_sznonrtsigcode;
  246 
  247 static void
  248 linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
  249 {
  250         register struct proc *p = curproc;
  251         register struct trapframe *regs;
  252         struct l_rt_sigframe *fp, frame;
  253         int oonstack;
  254 
  255         regs = p->p_md.md_regs;
  256         oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
  257 
  258 #ifdef DEBUG
  259         if (ldebug(rt_sendsig))
  260                 printf(ARGS(rt_sendsig, "%p, %d, %p, %lu"),
  261                     catcher, sig, (void*)mask, code);
  262 #endif
  263         /*
  264          * Allocate space for the signal handler context.
  265          */
  266         if ((p->p_flag & P_ALTSTACK) && !oonstack &&
  267             SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) {
  268                 fp = (struct l_rt_sigframe *)(p->p_sigstk.ss_sp +
  269                     p->p_sigstk.ss_size - sizeof(struct l_rt_sigframe));
  270                 p->p_sigstk.ss_flags |= SS_ONSTACK;
  271         } else
  272                 fp = (struct l_rt_sigframe *)regs->tf_esp - 1;
  273 
  274         /*
  275          * grow() will return FALSE if the fp will not fit inside the stack
  276          *      and the stack can not be grown. useracc will return FALSE
  277          *      if access is denied.
  278          */
  279         if ((grow_stack (p, (int)fp) == FALSE) ||
  280             !useracc((caddr_t)fp, sizeof (struct l_rt_sigframe), 
  281             VM_PROT_WRITE)) {
  282                 /*
  283                  * Process has trashed its stack; give it an illegal
  284                  * instruction to halt it in its tracks.
  285                  */
  286                 SIGACTION(p, SIGILL) = SIG_DFL;
  287                 SIGDELSET(p->p_sigignore, SIGILL);
  288                 SIGDELSET(p->p_sigcatch, SIGILL);
  289                 SIGDELSET(p->p_sigmask, SIGILL);
  290 #ifdef DEBUG
  291                 if (ldebug(rt_sendsig))
  292                         printf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"),
  293                             fp, oonstack);
  294 #endif
  295                 psignal(p, SIGILL);
  296                 return;
  297         }
  298 
  299         /*
  300          * Build the argument list for the signal handler.
  301          */
  302         if (p->p_sysent->sv_sigtbl)
  303                 if (sig <= p->p_sysent->sv_sigsize)
  304                         sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
  305 
  306         frame.sf_handler = catcher;
  307         frame.sf_sig = sig;
  308         frame.sf_siginfo = &fp->sf_si;
  309         frame.sf_ucontext = &fp->sf_sc;
  310 
  311         /* Fill siginfo structure. */
  312         frame.sf_si.lsi_signo = sig;
  313         frame.sf_si.lsi_code = code;
  314         frame.sf_si.lsi_addr = (void *)regs->tf_err;
  315 
  316         /*
  317          * Build the signal context to be used by sigreturn.
  318          */
  319         frame.sf_sc.uc_flags = 0;               /* XXX ??? */
  320         frame.sf_sc.uc_link = NULL;             /* XXX ??? */
  321 
  322         frame.sf_sc.uc_stack.ss_sp = p->p_sigstk.ss_sp;
  323         frame.sf_sc.uc_stack.ss_size = p->p_sigstk.ss_size;
  324         frame.sf_sc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
  325             ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
  326 
  327         bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
  328 
  329         frame.sf_sc.uc_mcontext.sc_mask   = frame.sf_sc.uc_sigmask.__bits[0];
  330         frame.sf_sc.uc_mcontext.sc_gs     = rgs();
  331         frame.sf_sc.uc_mcontext.sc_fs     = regs->tf_fs;
  332         frame.sf_sc.uc_mcontext.sc_es     = regs->tf_es;
  333         frame.sf_sc.uc_mcontext.sc_ds     = regs->tf_ds;
  334         frame.sf_sc.uc_mcontext.sc_edi    = regs->tf_edi;
  335         frame.sf_sc.uc_mcontext.sc_esi    = regs->tf_esi;
  336         frame.sf_sc.uc_mcontext.sc_ebp    = regs->tf_ebp;
  337         frame.sf_sc.uc_mcontext.sc_ebx    = regs->tf_ebx;
  338         frame.sf_sc.uc_mcontext.sc_edx    = regs->tf_edx;
  339         frame.sf_sc.uc_mcontext.sc_ecx    = regs->tf_ecx;
  340         frame.sf_sc.uc_mcontext.sc_eax    = regs->tf_eax;
  341         frame.sf_sc.uc_mcontext.sc_eip    = regs->tf_eip;
  342         frame.sf_sc.uc_mcontext.sc_cs     = regs->tf_cs;
  343         frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_eflags;
  344         frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_esp;
  345         frame.sf_sc.uc_mcontext.sc_ss     = regs->tf_ss;
  346         frame.sf_sc.uc_mcontext.sc_err    = regs->tf_err;
  347         frame.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
  348 
  349 #ifdef DEBUG
  350         if (ldebug(rt_sendsig))
  351                 printf(LMSG("rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"),
  352                     frame.sf_sc.uc_stack.ss_flags, p->p_sigstk.ss_sp,
  353                     p->p_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask);
  354 #endif
  355 
  356         if (copyout(&frame, fp, sizeof(frame)) != 0) {
  357                 /*
  358                  * Process has trashed its stack; give it an illegal
  359                  * instruction to halt it in its tracks.
  360                  */
  361                 sigexit(p, SIGILL);
  362                 /* NOTREACHED */
  363         }
  364 
  365         /*
  366          * Build context to run handler in.
  367          */
  368         regs->tf_esp = (int)fp;
  369         regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode) + 
  370             linux_sznonrtsigcode;
  371         regs->tf_eflags &= ~(PSL_T | PSL_VM);
  372         regs->tf_cs = _ucodesel;
  373         regs->tf_ds = _udatasel;
  374         regs->tf_es = _udatasel;
  375         regs->tf_fs = _udatasel;
  376         regs->tf_ss = _udatasel;
  377 }
  378 
  379 
  380 /*
  381  * Send an interrupt to process.
  382  *
  383  * Stack is set up to allow sigcode stored
  384  * in u. to call routine, followed by kcall
  385  * to sigreturn routine below.  After sigreturn
  386  * resets the signal mask, the stack, and the
  387  * frame pointer, it returns to the user
  388  * specified pc, psl.
  389  */
  390 
  391 static void
  392 linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
  393 {
  394         register struct proc *p = curproc;
  395         register struct trapframe *regs;
  396         struct l_sigframe *fp, frame;
  397         l_sigset_t lmask;
  398         int oonstack, i;
  399 
  400         if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
  401                 /* Signal handler installed with SA_SIGINFO. */
  402                 linux_rt_sendsig(catcher, sig, mask, code);
  403                 return;
  404         }
  405 
  406         regs = p->p_md.md_regs;
  407         oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
  408 
  409 #ifdef DEBUG
  410         if (ldebug(sendsig))
  411                 printf(ARGS(sendsig, "%p, %d, %p, %lu"),
  412                     catcher, sig, (void*)mask, code);
  413 #endif
  414 
  415         /*
  416          * Allocate space for the signal handler context.
  417          */
  418         if ((p->p_flag & P_ALTSTACK) && !oonstack &&
  419             SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) {
  420                 fp = (struct l_sigframe *)(p->p_sigstk.ss_sp +
  421                     p->p_sigstk.ss_size - sizeof(struct l_sigframe));
  422                 p->p_sigstk.ss_flags |= SS_ONSTACK;
  423         } else
  424                 fp = (struct l_sigframe *)regs->tf_esp - 1;
  425 
  426         /*
  427          * grow() will return FALSE if the fp will not fit inside the stack
  428          *      and the stack can not be grown. useracc will return FALSE
  429          *      if access is denied.
  430          */
  431         if ((grow_stack (p, (int)fp) == FALSE) ||
  432             !useracc((caddr_t)fp, sizeof (struct l_sigframe), 
  433             VM_PROT_WRITE)) {
  434                 /*
  435                  * Process has trashed its stack; give it an illegal
  436                  * instruction to halt it in its tracks.
  437                  */
  438                 SIGACTION(p, SIGILL) = SIG_DFL;
  439                 SIGDELSET(p->p_sigignore, SIGILL);
  440                 SIGDELSET(p->p_sigcatch, SIGILL);
  441                 SIGDELSET(p->p_sigmask, SIGILL);
  442                 psignal(p, SIGILL);
  443                 return;
  444         }
  445 
  446         /*
  447          * Build the argument list for the signal handler.
  448          */
  449         if (p->p_sysent->sv_sigtbl)
  450                 if (sig <= p->p_sysent->sv_sigsize)
  451                         sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
  452 
  453         frame.sf_handler = catcher;
  454         frame.sf_sig = sig;
  455 
  456         bsd_to_linux_sigset(mask, &lmask);
  457 
  458         /*
  459          * Build the signal context to be used by sigreturn.
  460          */
  461         frame.sf_sc.sc_mask   = lmask.__bits[0];
  462         frame.sf_sc.sc_gs     = rgs();
  463         frame.sf_sc.sc_fs     = regs->tf_fs;
  464         frame.sf_sc.sc_es     = regs->tf_es;
  465         frame.sf_sc.sc_ds     = regs->tf_ds;
  466         frame.sf_sc.sc_edi    = regs->tf_edi;
  467         frame.sf_sc.sc_esi    = regs->tf_esi;
  468         frame.sf_sc.sc_ebp    = regs->tf_ebp;
  469         frame.sf_sc.sc_ebx    = regs->tf_ebx;
  470         frame.sf_sc.sc_edx    = regs->tf_edx;
  471         frame.sf_sc.sc_ecx    = regs->tf_ecx;
  472         frame.sf_sc.sc_eax    = regs->tf_eax;
  473         frame.sf_sc.sc_eip    = regs->tf_eip;
  474         frame.sf_sc.sc_cs     = regs->tf_cs;
  475         frame.sf_sc.sc_eflags = regs->tf_eflags;
  476         frame.sf_sc.sc_esp_at_signal = regs->tf_esp;
  477         frame.sf_sc.sc_ss     = regs->tf_ss;
  478         frame.sf_sc.sc_err    = regs->tf_err;
  479         frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code);
  480 
  481         bzero(&frame.sf_fpstate, sizeof(struct l_fpstate));
  482 
  483         for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
  484                 frame.sf_extramask[i] = lmask.__bits[i+1];
  485 
  486         if (copyout(&frame, fp, sizeof(frame)) != 0) {
  487                 /*
  488                  * Process has trashed its stack; give it an illegal
  489                  * instruction to halt it in its tracks.
  490                  */
  491                 sigexit(p, SIGILL);
  492                 /* NOTREACHED */
  493         }
  494 
  495         /*
  496          * Build context to run handler in.
  497          */
  498         regs->tf_esp = (int)fp;
  499         regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
  500         regs->tf_eflags &= ~(PSL_T | PSL_VM);
  501         regs->tf_cs = _ucodesel;
  502         regs->tf_ds = _udatasel;
  503         regs->tf_es = _udatasel;
  504         regs->tf_fs = _udatasel;
  505         regs->tf_ss = _udatasel;
  506 }
  507 
  508 /*
  509  * System call to cleanup state after a signal
  510  * has been taken.  Reset signal mask and
  511  * stack state from context left by sendsig (above).
  512  * Return to previous pc and psl as specified by
  513  * context left by sendsig. Check carefully to
  514  * make sure that the user has not modified the
  515  * psl to gain improper privileges or to cause
  516  * a machine fault.
  517  */
  518 int
  519 linux_sigreturn(p, args)
  520         struct proc *p;
  521         struct linux_sigreturn_args *args;
  522 {
  523         struct l_sigframe frame;
  524         register struct trapframe *regs;
  525         l_sigset_t lmask;
  526         int eflags, i;
  527 
  528         regs = p->p_md.md_regs;
  529 
  530 #ifdef DEBUG
  531         if (ldebug(sigreturn))
  532                 printf(ARGS(sigreturn, "%p"), (void *)args->sfp);
  533 #endif
  534         /*
  535          * The trampoline code hands us the sigframe.
  536          * It is unsafe to keep track of it ourselves, in the event that a
  537          * program jumps out of a signal handler.
  538          */
  539         if (copyin((caddr_t)args->sfp, &frame, sizeof(frame)) != 0)
  540                 return (EFAULT);
  541 
  542         /*
  543          * Check for security violations.
  544          */
  545 #define EFLAGS_SECURE(ef, oef)  ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
  546         eflags = frame.sf_sc.sc_eflags;
  547         /*
  548          * XXX do allow users to change the privileged flag PSL_RF.  The
  549          * cpu sets PSL_RF in tf_eflags for faults.  Debuggers should
  550          * sometimes set it there too.  tf_eflags is kept in the signal
  551          * context during signal handling and there is no other place
  552          * to remember it, so the PSL_RF bit may be corrupted by the
  553          * signal handler without us knowing.  Corruption of the PSL_RF
  554          * bit at worst causes one more or one less debugger trap, so
  555          * allowing it is fairly harmless.
  556          */
  557         if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
  558                 return(EINVAL);
  559         }
  560 
  561         /*
  562          * Don't allow users to load a valid privileged %cs.  Let the
  563          * hardware check for invalid selectors, excess privilege in
  564          * other selectors, invalid %eip's and invalid %esp's.
  565          */
  566 #define CS_SECURE(cs)   (ISPL(cs) == SEL_UPL)
  567         if (!CS_SECURE(frame.sf_sc.sc_cs)) {
  568                 trapsignal(p, SIGBUS, T_PROTFLT);
  569                 return(EINVAL);
  570         }
  571 
  572         p->p_sigstk.ss_flags &= ~SS_ONSTACK;
  573         lmask.__bits[0] = frame.sf_sc.sc_mask;
  574         for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
  575                 lmask.__bits[i+1] = frame.sf_extramask[i];
  576         linux_to_bsd_sigset(&lmask, &p->p_sigmask);
  577         SIG_CANTMASK(p->p_sigmask);
  578 
  579         /*
  580          * Restore signal context.
  581          */
  582         /* %gs was restored by the trampoline. */
  583         regs->tf_fs     = frame.sf_sc.sc_fs;
  584         regs->tf_es     = frame.sf_sc.sc_es;
  585         regs->tf_ds     = frame.sf_sc.sc_ds;
  586         regs->tf_edi    = frame.sf_sc.sc_edi;
  587         regs->tf_esi    = frame.sf_sc.sc_esi;
  588         regs->tf_ebp    = frame.sf_sc.sc_ebp;
  589         regs->tf_ebx    = frame.sf_sc.sc_ebx;
  590         regs->tf_edx    = frame.sf_sc.sc_edx;
  591         regs->tf_ecx    = frame.sf_sc.sc_ecx;
  592         regs->tf_eax    = frame.sf_sc.sc_eax;
  593         regs->tf_eip    = frame.sf_sc.sc_eip;
  594         regs->tf_cs     = frame.sf_sc.sc_cs;
  595         regs->tf_eflags = eflags;
  596         regs->tf_esp    = frame.sf_sc.sc_esp_at_signal;
  597         regs->tf_ss     = frame.sf_sc.sc_ss;
  598 
  599         return (EJUSTRETURN);
  600 }
  601 
  602 /*
  603  * System call to cleanup state after a signal
  604  * has been taken.  Reset signal mask and
  605  * stack state from context left by rt_sendsig (above).
  606  * Return to previous pc and psl as specified by
  607  * context left by sendsig. Check carefully to
  608  * make sure that the user has not modified the
  609  * psl to gain improper privileges or to cause
  610  * a machine fault.
  611  */
  612 int
  613 linux_rt_sigreturn(p, args)
  614         struct proc *p;
  615         struct linux_rt_sigreturn_args *args;
  616 {
  617         struct sigaltstack_args sasargs;
  618         struct l_ucontext uc;
  619         struct l_sigcontext *context;
  620         l_stack_t *lss;
  621         stack_t *ss;
  622         register struct trapframe *regs;
  623         int eflags;
  624         caddr_t sg = stackgap_init();
  625 
  626         regs = p->p_md.md_regs;
  627 
  628 #ifdef DEBUG
  629         if (ldebug(rt_sigreturn))
  630                 printf(ARGS(rt_sigreturn, "%p"), (void *)args->ucp);
  631 #endif
  632         /*
  633          * The trampoline code hands us the ucontext.
  634          * It is unsafe to keep track of it ourselves, in the event that a
  635          * program jumps out of a signal handler.
  636          */
  637         if (copyin((caddr_t)args->ucp, &uc, sizeof(uc)) != 0)
  638                 return (EFAULT);
  639 
  640         context = &uc.uc_mcontext;
  641 
  642         /*
  643          * Check for security violations.
  644          */
  645 #define EFLAGS_SECURE(ef, oef)  ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
  646         eflags = context->sc_eflags;
  647         /*
  648          * XXX do allow users to change the privileged flag PSL_RF.  The
  649          * cpu sets PSL_RF in tf_eflags for faults.  Debuggers should
  650          * sometimes set it there too.  tf_eflags is kept in the signal
  651          * context during signal handling and there is no other place
  652          * to remember it, so the PSL_RF bit may be corrupted by the
  653          * signal handler without us knowing.  Corruption of the PSL_RF
  654          * bit at worst causes one more or one less debugger trap, so
  655          * allowing it is fairly harmless.
  656          */
  657         if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
  658                 return(EINVAL);
  659         }
  660 
  661         /*
  662          * Don't allow users to load a valid privileged %cs.  Let the
  663          * hardware check for invalid selectors, excess privilege in
  664          * other selectors, invalid %eip's and invalid %esp's.
  665          */
  666 #define CS_SECURE(cs)   (ISPL(cs) == SEL_UPL)
  667         if (!CS_SECURE(context->sc_cs)) {
  668                 trapsignal(p, SIGBUS, T_PROTFLT);
  669                 return(EINVAL);
  670         }
  671 
  672         p->p_sigstk.ss_flags &= ~SS_ONSTACK;
  673         linux_to_bsd_sigset(&uc.uc_sigmask, &p->p_sigmask);
  674         SIG_CANTMASK(p->p_sigmask);
  675 
  676         /*
  677          * Restore signal context
  678          */
  679         /* %gs was restored by the trampoline. */
  680         regs->tf_fs     = context->sc_fs;
  681         regs->tf_es     = context->sc_es;
  682         regs->tf_ds     = context->sc_ds;
  683         regs->tf_edi    = context->sc_edi;
  684         regs->tf_esi    = context->sc_esi;
  685         regs->tf_ebp    = context->sc_ebp;
  686         regs->tf_ebx    = context->sc_ebx;
  687         regs->tf_edx    = context->sc_edx;
  688         regs->tf_ecx    = context->sc_ecx;
  689         regs->tf_eax    = context->sc_eax;
  690         regs->tf_eip    = context->sc_eip;
  691         regs->tf_cs     = context->sc_cs;
  692         regs->tf_eflags = eflags;
  693         regs->tf_esp    = context->sc_esp_at_signal;
  694         regs->tf_ss     = context->sc_ss;
  695 
  696         /*
  697          * call sigaltstack & ignore results..
  698          */
  699         ss = stackgap_alloc(&sg, sizeof(stack_t));
  700         lss = &uc.uc_stack;
  701         ss->ss_sp = lss->ss_sp;
  702         ss->ss_size = lss->ss_size;
  703         ss->ss_flags = linux_to_bsd_sigaltstack(lss->ss_flags);
  704 
  705 #ifdef DEBUG
  706         if (ldebug(rt_sigreturn))
  707                 printf(LMSG("rt_sigret flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"),
  708                     ss->ss_flags, ss->ss_sp, ss->ss_size, context->sc_mask);
  709 #endif
  710         sasargs.ss = ss;
  711         sasargs.oss = NULL;
  712         (void) sigaltstack(p, &sasargs);
  713 
  714         return (EJUSTRETURN);
  715 }
  716 
  717 static void
  718 linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params)
  719 {
  720         args[0] = tf->tf_ebx;
  721         args[1] = tf->tf_ecx;
  722         args[2] = tf->tf_edx;
  723         args[3] = tf->tf_esi;
  724         args[4] = tf->tf_edi;
  725         args[5] = tf->tf_ebp;   /* Unconfirmed */
  726         *params = NULL;         /* no copyin */
  727 }
  728 
  729 /*
  730  * If a linux binary is exec'ing something, try this image activator 
  731  * first.  We override standard shell script execution in order to
  732  * be able to modify the interpreter path.  We only do this if a linux
  733  * binary is doing the exec, so we do not create an EXEC module for it.
  734  */
  735 static int      exec_linux_imgact_try __P((struct image_params *iparams));
  736 
  737 static int
  738 exec_linux_imgact_try(imgp)
  739     struct image_params *imgp;
  740 {
  741     const char *head = (const char *)imgp->image_header;
  742     int error = -1;
  743 
  744     /*
  745      * The interpreter for shell scripts run from a linux binary needs
  746      * to be located in /compat/linux if possible in order to recursively
  747      * maintain linux path emulation.
  748      */
  749     if (((const short *)head)[0] == SHELLMAGIC) {
  750             /*
  751              * Run our normal shell image activator.  If it succeeds attempt
  752              * to use the alternate path for the interpreter.  If an alternate
  753              * path is found, use our stringspace to store it.
  754              */
  755             if ((error = exec_shell_imgact(imgp)) == 0) {
  756                     char *rpath = NULL;
  757 
  758                     linux_emul_find(imgp->proc, NULL, linux_emul_path, 
  759                         imgp->interpreter_name, &rpath, 0);
  760                     if (rpath != imgp->interpreter_name) {
  761                             int len = strlen(rpath) + 1;
  762 
  763                             if (len <= MAXSHELLCMDLEN) {
  764                                 memcpy(imgp->interpreter_name, rpath, len);
  765                             }
  766                             free(rpath, M_TEMP);
  767                     }
  768             }
  769     }
  770     return(error);
  771 }
  772 
  773 struct sysentvec linux_sysvec = {
  774         LINUX_SYS_MAXSYSCALL,
  775         linux_sysent,
  776         0xff,
  777         LINUX_SIGTBLSZ,
  778         bsd_to_linux_signal,
  779         ELAST + 1, 
  780         bsd_to_linux_errno,
  781         translate_traps,
  782         linux_fixup,
  783         linux_sendsig,
  784         linux_sigcode,  
  785         &linux_szsigcode,
  786         linux_prepsyscall,
  787         "Linux a.out",
  788         aout_coredump,
  789         exec_linux_imgact_try,
  790         LINUX_MINSIGSTKSZ
  791 };
  792 
  793 struct sysentvec elf_linux_sysvec = {
  794         LINUX_SYS_MAXSYSCALL,
  795         linux_sysent,
  796         0xff,
  797         LINUX_SIGTBLSZ,
  798         bsd_to_linux_signal,
  799         ELAST + 1,
  800         bsd_to_linux_errno,
  801         translate_traps,
  802         elf_linux_fixup,
  803         linux_sendsig,
  804         linux_sigcode,
  805         &linux_szsigcode,
  806         linux_prepsyscall,
  807         "Linux ELF",
  808         elf_coredump,
  809         exec_linux_imgact_try,
  810         LINUX_MINSIGSTKSZ
  811 };
  812 
  813 static Elf32_Brandinfo linux_brand = {
  814                                         ELFOSABI_LINUX,
  815                                         "Linux",
  816                                         "/compat/linux",
  817                                         "/lib/ld-linux.so.1",
  818                                         &elf_linux_sysvec
  819                                  };
  820 
  821 static Elf32_Brandinfo linux_glibc2brand = {
  822                                         ELFOSABI_LINUX,
  823                                         "Linux",
  824                                         "/compat/linux",
  825                                         "/lib/ld-linux.so.2",
  826                                         &elf_linux_sysvec
  827                                  };
  828 
  829 Elf32_Brandinfo *linux_brandlist[] = {
  830                                         &linux_brand,
  831                                         &linux_glibc2brand,
  832                                         NULL
  833                                 };
  834 
  835 static int
  836 linux_elf_modevent(module_t mod, int type, void *data)
  837 {
  838         Elf32_Brandinfo **brandinfo;
  839         int error;
  840 
  841         error = 0;
  842 
  843         switch(type) {
  844         case MOD_LOAD:
  845                 for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
  846                      ++brandinfo)
  847                         if (elf_insert_brand_entry(*brandinfo) < 0)
  848                                 error = EINVAL;
  849                 if (error == 0) {
  850                         linux_ioctl_register_handlers(
  851                                 &linux_ioctl_handler_set);
  852                         if (bootverbose)
  853                                 printf("Linux ELF exec handler installed\n");
  854                 } else
  855                         printf("cannot insert Linux ELF brand handler\n");
  856                 break;
  857         case MOD_UNLOAD:
  858                 for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
  859                      ++brandinfo)
  860                         if (elf_brand_inuse(*brandinfo))
  861                                 error = EBUSY;
  862                 if (error == 0) {
  863                         for (brandinfo = &linux_brandlist[0];
  864                              *brandinfo != NULL; ++brandinfo)
  865                                 if (elf_remove_brand_entry(*brandinfo) < 0)
  866                                         error = EINVAL;
  867                 }
  868                 if (error == 0) {
  869                         linux_ioctl_unregister_handlers(
  870                                 &linux_ioctl_handler_set);
  871                         if (bootverbose)
  872                                 printf("Linux ELF exec handler removed\n");
  873                 } else
  874                         printf("Could not deinstall ELF interpreter entry\n");
  875                 break;
  876         default:
  877                 break;
  878         }
  879         return error;
  880 }
  881 
  882 static moduledata_t linux_elf_mod = {
  883         "linuxelf",
  884         linux_elf_modevent,
  885         0
  886 };
  887 
  888 DECLARE_MODULE(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);

Cache object: 26099d2133ecdacd5a6f5b71a5a2faea


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.