root/kernel/exec_domain.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. no_lcall7
  2. lookup_exec_domain
  3. register_exec_domain
  4. unregister_exec_domain
  5. sys_personality

   1 #include <linux/personality.h>
   2 #include <linux/ptrace.h>
   3 #include <linux/sched.h>
   4 #include <linux/mm.h>
   5 
   6 static asmlinkage void no_lcall7(struct pt_regs * regs);
   7 
   8 
   9 static unsigned long ident_map[32] = {
  10         0,      1,      2,      3,      4,      5,      6,      7,
  11         8,      9,      10,     11,     12,     13,     14,     15,
  12         16,     17,     18,     19,     20,     21,     22,     23,
  13         24,     25,     26,     27,     28,     29,     30,     31
  14 };
  15 
  16 struct exec_domain default_exec_domain = {
  17         "Linux",        /* name */
  18         no_lcall7,      /* lcall7 causes a seg fault. */
  19         0, 0xff,        /* All personalities. */
  20         ident_map,      /* Identity map signals. */
  21         ident_map,      /*  - both ways. */
  22         NULL,           /* No usage counter. */
  23         NULL            /* Nothing after this in the list. */
  24 };
  25 
  26 static struct exec_domain *exec_domains = &default_exec_domain;
  27 
  28 
  29 static asmlinkage void no_lcall7(struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31 
  32   /*
  33    * This may have been a static linked SVr4 binary, so we would have the
  34    * personality set incorrectly.  Check to see whether SVr4 is available,
  35    * and use it, otherwise give the user a SEGV.
  36    */
  37         if (current->exec_domain && current->exec_domain->use_count)
  38                 (*current->exec_domain->use_count)--;
  39 
  40         current->personality = PER_SVR4;
  41         current->exec_domain = lookup_exec_domain(current->personality);
  42 
  43         if (current->exec_domain && current->exec_domain->use_count)
  44                 (*current->exec_domain->use_count)++;
  45 
  46         if (current->exec_domain && current->exec_domain->handler
  47         && current->exec_domain->handler != no_lcall7) {
  48                 current->exec_domain->handler(regs);
  49                 return;
  50         }
  51 
  52         send_sig(SIGSEGV, current, 1);
  53 }
  54 
  55 struct exec_domain *lookup_exec_domain(unsigned long personality)
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57         unsigned long pers = personality & PER_MASK;
  58         struct exec_domain *it;
  59 
  60         for (it=exec_domains; it; it=it->next)
  61                 if (pers >= it->pers_low
  62                 && pers <= it->pers_high)
  63                         return it;
  64 
  65         /* Should never get this far. */
  66         printk(KERN_ERR "No execution domain for personality 0x%02lx\n", pers);
  67         return NULL;
  68 }
  69 
  70 int register_exec_domain(struct exec_domain *it)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72         struct exec_domain *tmp;
  73 
  74         if (!it)
  75                 return -EINVAL;
  76         if (it->next)
  77                 return -EBUSY;
  78         for (tmp=exec_domains; tmp; tmp=tmp->next)
  79                 if (tmp == it)
  80                         return -EBUSY;
  81         it->next = exec_domains;
  82         exec_domains = it;
  83         return 0;
  84 }
  85 
  86 int unregister_exec_domain(struct exec_domain *it)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88         struct exec_domain ** tmp;
  89 
  90         tmp = &exec_domains;
  91         while (*tmp) {
  92                 if (it == *tmp) {
  93                         *tmp = it->next;
  94                         it->next = NULL;
  95                         return 0;
  96                 }
  97                 tmp = &(*tmp)->next;
  98         }
  99         return -EINVAL;
 100 }
 101 
 102 asmlinkage int sys_personality(unsigned long personality)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104         struct exec_domain *it;
 105         unsigned long old_personality;
 106 
 107         if (personality == 0xffffffff)
 108                 return current->personality;
 109 
 110         it = lookup_exec_domain(personality);
 111         if (!it)
 112                 return -EINVAL;
 113 
 114         old_personality = current->personality;
 115         if (current->exec_domain && current->exec_domain->use_count)
 116                 (*current->exec_domain->use_count)--;
 117         current->personality = personality;
 118         current->exec_domain = it;
 119         if (current->exec_domain->use_count)
 120                 (*current->exec_domain->use_count)++;
 121 
 122         return old_personality;
 123 }

/* [previous][next][first][last][top][bottom][index][help] */