2 #include <linux/smp_lock.h>
3 #include <linux/module.h>
5 static asmlinkage
void no_lcall7(int segment
, struct pt_regs
* regs
);
8 static unsigned long ident_map
[32] = {
9 0, 1, 2, 3, 4, 5, 6, 7,
10 8, 9, 10, 11, 12, 13, 14, 15,
11 16, 17, 18, 19, 20, 21, 22, 23,
12 24, 25, 26, 27, 28, 29, 30, 31
15 struct exec_domain default_exec_domain
= {
17 no_lcall7
, /* lcall7 causes a seg fault. */
18 0, 0xff, /* All personalities. */
19 ident_map
, /* Identity map signals. */
20 ident_map
, /* - both ways. */
21 NULL
, /* No usage counter. */
22 NULL
/* Nothing after this in the list. */
25 static struct exec_domain
*exec_domains
= &default_exec_domain
;
28 static asmlinkage
void no_lcall7(int segment
, struct pt_regs
* regs
)
31 * This may have been a static linked SVr4 binary, so we would have the
32 * personality set incorrectly. Check to see whether SVr4 is available,
33 * and use it, otherwise give the user a SEGV.
35 if (current
->exec_domain
&& current
->exec_domain
->module
)
36 __MOD_DEC_USE_COUNT(current
->exec_domain
->module
);
38 current
->personality
= PER_SVR4
;
39 current
->exec_domain
= lookup_exec_domain(current
->personality
);
41 if (current
->exec_domain
&& current
->exec_domain
->module
)
42 __MOD_INC_USE_COUNT(current
->exec_domain
->module
);
44 if (current
->exec_domain
&& current
->exec_domain
->handler
45 && current
->exec_domain
->handler
!= no_lcall7
) {
46 current
->exec_domain
->handler(segment
, regs
);
50 send_sig(SIGSEGV
, current
, 1);
53 struct exec_domain
*lookup_exec_domain(unsigned long personality
)
55 unsigned long pers
= personality
& PER_MASK
;
56 struct exec_domain
*it
;
58 for (it
=exec_domains
; it
; it
=it
->next
)
59 if (pers
>= it
->pers_low
60 && pers
<= it
->pers_high
)
63 /* Should never get this far. */
64 printk(KERN_ERR
"No execution domain for personality 0x%02lx\n", pers
);
68 int register_exec_domain(struct exec_domain
*it
)
70 struct exec_domain
*tmp
;
76 for (tmp
=exec_domains
; tmp
; tmp
=tmp
->next
)
79 it
->next
= exec_domains
;
84 int unregister_exec_domain(struct exec_domain
*it
)
86 struct exec_domain
** tmp
;
100 asmlinkage
long sys_personality(unsigned long personality
)
102 struct exec_domain
*it
;
103 unsigned long old_personality
;
107 ret
= current
->personality
;
108 if (personality
== 0xffffffff)
112 it
= lookup_exec_domain(personality
);
116 old_personality
= current
->personality
;
117 if (current
->exec_domain
&& current
->exec_domain
->module
)
118 __MOD_DEC_USE_COUNT(current
->exec_domain
->module
);
119 current
->personality
= personality
;
120 current
->exec_domain
= it
;
121 if (current
->exec_domain
->module
)
122 __MOD_INC_USE_COUNT(current
->exec_domain
->module
);
123 ret
= old_personality
;
129 int get_exec_domain_list(char * page
)
132 struct exec_domain
* e
;
134 for (e
=exec_domains
; e
&& len
< PAGE_SIZE
- 80; e
=e
->next
)
135 len
+= sprintf(page
+len
, "%d-%d\t%-16s\t[%s]\n",
136 e
->pers_low
, e
->pers_high
, e
->name
,
137 e
->module
? e
->module
->name
: "kernel");