Ядро Linux в комментариях

       

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 }



Содержание раздела