2 #include <linux/smp_lock.h>
3 #include <linux/module.h>
5 static asmlinkage
void no_lcall7(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(struct pt_regs
* regs
)
32 * This may have been a static linked SVr4 binary, so we would have the
33 * personality set incorrectly. Check to see whether SVr4 is available,
34 * and use it, otherwise give the user a SEGV.
36 if (current
->exec_domain
&& current
->exec_domain
->module
)
37 __MOD_DEC_USE_COUNT(current
->exec_domain
->module
);
39 current
->personality
= PER_SVR4
;
40 current
->exec_domain
= lookup_exec_domain(current
->personality
);
42 if (current
->exec_domain
&& current
->exec_domain
->module
)
43 __MOD_INC_USE_COUNT(current
->exec_domain
->module
);
45 if (current
->exec_domain
&& current
->exec_domain
->handler
46 && current
->exec_domain
->handler
!= no_lcall7
) {
47 current
->exec_domain
->handler(regs
);
51 send_sig(SIGSEGV
, current
, 1);
54 struct exec_domain
*lookup_exec_domain(unsigned long personality
)
56 unsigned long pers
= personality
& PER_MASK
;
57 struct exec_domain
*it
;
59 for (it
=exec_domains
; it
; it
=it
->next
)
60 if (pers
>= it
->pers_low
61 && pers
<= it
->pers_high
)
64 /* Should never get this far. */
65 printk(KERN_ERR
"No execution domain for personality 0x%02lx\n", pers
);
69 int register_exec_domain(struct exec_domain
*it
)
71 struct exec_domain
*tmp
;
77 for (tmp
=exec_domains
; tmp
; tmp
=tmp
->next
)
80 it
->next
= exec_domains
;
85 int unregister_exec_domain(struct exec_domain
*it
)
87 struct exec_domain
** tmp
;
101 asmlinkage
int sys_personality(unsigned long personality
)
103 struct exec_domain
*it
;
104 unsigned long old_personality
;
108 ret
= current
->personality
;
109 if (personality
== 0xffffffff)
113 it
= lookup_exec_domain(personality
);
117 old_personality
= current
->personality
;
118 if (current
->exec_domain
&& current
->exec_domain
->module
)
119 __MOD_DEC_USE_COUNT(current
->exec_domain
->module
);
120 current
->personality
= personality
;
121 current
->exec_domain
= it
;
122 if (current
->exec_domain
->module
)
123 __MOD_INC_USE_COUNT(current
->exec_domain
->module
);
124 ret
= old_personality
;