This source file includes following definitions.
- no_lcall7
- lookup_exec_domain
- register_exec_domain
- unregister_exec_domain
- 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",
18 no_lcall7,
19 0, 0xff,
20 ident_map,
21 ident_map,
22 NULL,
23 NULL
24 };
25
26 static struct exec_domain *exec_domains = &default_exec_domain;
27
28
29 static asmlinkage void no_lcall7(struct pt_regs * regs)
30 {
31
32
33
34
35
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)
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
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)
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)
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)
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 }