netlib.narod.ru< Назад | Оглавление | Далее >

kernel/exec_domain.c

22793 #include <linux/mm.h>
22794 #include <linux/smp_lock.h>
22795 #include <linux/module.h>
22796 
22797 static asmlinkage void no_lcall7(struct pt_regs * regs);
22798 
22799 
22800 static unsigned long ident_map[32] = {
22801    0,    1,    2,    3,    4,    5,    6,    7,
22802    8,    9,   10,   11,   12,   13,   14,   15,
22803   16,   17,   18,   19,   20,   21,   22,   23,
22804   24,   25,   26,   27,   28,   29,   30,   31
22805 };
22806 
22807 struct exec_domain default_exec_domain = {
22808   "Linux",        /* name */
22809   no_lcall7,      /* lcall7 causes a seg fault. */
22810   0, 0xff,        /* All personalities. */
22811   ident_map,      /* Identity map signals. */
22812   ident_map,      /*  - both ways. */
22813   NULL,           /* No usage counter. */
22814   NULL            /* Nothing after this in the list. */
22815 };
22816 
22817 static struct exec_domain *exec_domains =
22818   &default_exec_domain;
22819 
22820 static asmlinkage void no_lcall7(struct pt_regs * regs)
22821 {
22822 
22823   /* This may have been a static linked SVr4 binary, so
22824    * we would have the personality set incorrectly.
22825    * Check to see whether SVr4 is available, and use it,
22826    * otherwise give the user a SEGV.  */
22827   if (current->exec_domain &&
22828       current->exec_domain->module)
22829     __MOD_DEC_USE_COUNT(current->exec_domain->module);
22830 
22831   current->personality = PER_SVR4;
22832   current->exec_domain =
22833     lookup_exec_domain(current->personality);
22834 
22835   if (current->exec_domain &&
22836       current->exec_domain->module)
22837     __MOD_INC_USE_COUNT(current->exec_domain->module);
22838 
22839   if (current->exec_domain &&
22840       current->exec_domain->handler &&
22841       current->exec_domain->handler != no_lcall7) {
22842     current->exec_domain->handler(regs);
22843     return;
22844   }
22845 
22846   send_sig(SIGSEGV, current, 1);
22847 }
22848 
22849 struct exec_domain *lookup_exec_domain(
22850   unsigned long personality)
22851 {
22852   unsigned long pers = personality & PER_MASK;
22853   struct exec_domain *it;
22854 
22855   for (it=exec_domains; it; it=it->next)
22856     if (pers >= it->pers_low
22857     && pers <= it->pers_high)
22858       return it;
22859 
22860   /* Should never get this far. */
22861   printk(KERN_ERR "No execution domain for personality "
22862          "0x%02lx\n", pers);
22863   return NULL;
22864 }
22865 
22866 int register_exec_domain(struct exec_domain *it)
22867 {
22868   struct exec_domain *tmp;
22869 
22870   if (!it)
22871     return -EINVAL;
22872   if (it->next)
22873     return -EBUSY;
22874   for (tmp=exec_domains; tmp; tmp=tmp->next)
22875     if (tmp == it)
22876       return -EBUSY;
22877   it->next = exec_domains;
22878   exec_domains = it;
22879   return 0;
22880 }
22881 
22882 int unregister_exec_domain(struct exec_domain *it)
22883 {
22884   struct exec_domain ** tmp;
22885 
22886   tmp = &exec_domains;
22887   while (*tmp) {
22888     if (it == *tmp) {
22889       *tmp = it->next;
22890       it->next = NULL;
22891       return 0;
22892     }
22893     tmp = &(*tmp)->next;
22894   }
22895   return -EINVAL;
22896 }
22897 
22898 asmlinkage int sys_personality(unsigned long personality)
22899 {
22900   struct exec_domain *it;
22901   unsigned long old_personality;
22902   int ret;
22903 
22904   lock_kernel();
22905   ret = current->personality;
22906   if (personality == 0xffffffff)
22907     goto out;
22908 
22909   ret = -EINVAL;
22910   it = lookup_exec_domain(personality);
22911   if (!it)
22912     goto out;
22913 
22914   old_personality = current->personality;
22915   if (current->exec_domain &&
22916       current->exec_domain->module)
22917     __MOD_DEC_USE_COUNT(current->exec_domain->module);
22918   current->personality = personality;
22919   current->exec_domain = it;
22920   if (current->exec_domain->module)
22921     __MOD_INC_USE_COUNT(current->exec_domain->module);
22922   ret = old_personality;
22923 out:
22924   unlock_kernel();
22925   return ret;
22926 }

netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz