1 #include <linux/personality.h>
2 #include <linux/ptrace.h>
3 #include <linux/sched.h>
6 #include <linux/smp_lock.h>
7 #include <linux/module.h>
9 static asmlinkage
void no_lcall7(struct pt_regs
* regs
);
12 static unsigned long ident_map
[32] = {
13 0, 1, 2, 3, 4, 5, 6, 7,
14 8, 9, 10, 11, 12, 13, 14, 15,
15 16, 17, 18, 19, 20, 21, 22, 23,
16 24, 25, 26, 27, 28, 29, 30, 31
19 struct exec_domain default_exec_domain
= {
21 no_lcall7
, /* lcall7 causes a seg fault. */
22 0, 0xff, /* All personalities. */
23 ident_map
, /* Identity map signals. */
24 ident_map
, /* - both ways. */
25 NULL
, /* No usage counter. */
26 NULL
/* Nothing after this in the list. */
29 static struct exec_domain
*exec_domains
= &default_exec_domain
;
32 static asmlinkage
void no_lcall7(struct pt_regs
* regs
)
36 * This may have been a static linked SVr4 binary, so we would have the
37 * personality set incorrectly. Check to see whether SVr4 is available,
38 * and use it, otherwise give the user a SEGV.
40 if (current
->exec_domain
&& current
->exec_domain
->module
)
41 __MOD_DEC_USE_COUNT(current
->exec_domain
->module
);
43 current
->personality
= PER_SVR4
;
44 current
->exec_domain
= lookup_exec_domain(current
->personality
);
46 if (current
->exec_domain
&& current
->exec_domain
->module
)
47 __MOD_INC_USE_COUNT(current
->exec_domain
->module
);
49 if (current
->exec_domain
&& current
->exec_domain
->handler
50 && current
->exec_domain
->handler
!= no_lcall7
) {
51 current
->exec_domain
->handler(regs
);
55 send_sig(SIGSEGV
, current
, 1);
58 struct exec_domain
*lookup_exec_domain(unsigned long personality
)
60 unsigned long pers
= personality
& PER_MASK
;
61 struct exec_domain
*it
;
63 for (it
=exec_domains
; it
; it
=it
->next
)
64 if (pers
>= it
->pers_low
65 && pers
<= it
->pers_high
)
68 /* Should never get this far. */
69 printk(KERN_ERR
"No execution domain for personality 0x%02lx\n", pers
);
73 int register_exec_domain(struct exec_domain
*it
)
75 struct exec_domain
*tmp
;
81 for (tmp
=exec_domains
; tmp
; tmp
=tmp
->next
)
84 it
->next
= exec_domains
;
89 int unregister_exec_domain(struct exec_domain
*it
)
91 struct exec_domain
** tmp
;
105 asmlinkage
int sys_personality(unsigned long personality
)
107 struct exec_domain
*it
;
108 unsigned long old_personality
;
112 ret
= current
->personality
;
113 if (personality
== 0xffffffff)
117 it
= lookup_exec_domain(personality
);
121 old_personality
= current
->personality
;
122 if (current
->exec_domain
&& current
->exec_domain
->module
)
123 __MOD_DEC_USE_COUNT(current
->exec_domain
->module
);
124 current
->personality
= personality
;
125 current
->exec_domain
= it
;
126 if (current
->exec_domain
->module
)
127 __MOD_INC_USE_COUNT(current
->exec_domain
->module
);
128 ret
= old_personality
;