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
;
26 static rwlock_t exec_domains_lock
= RW_LOCK_UNLOCKED
;
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 set_personality(PER_SVR4
);
37 if (current
->exec_domain
&& current
->exec_domain
->handler
38 && current
->exec_domain
->handler
!= no_lcall7
) {
39 current
->exec_domain
->handler(segment
, regs
);
43 send_sig(SIGSEGV
, current
, 1);
46 static struct exec_domain
*lookup_exec_domain(unsigned long personality
)
48 unsigned long pers
= personality
& PER_MASK
;
49 struct exec_domain
*it
;
51 read_lock(&exec_domains_lock
);
52 for (it
=exec_domains
; it
; it
=it
->next
)
53 if (pers
>= it
->pers_low
&& pers
<= it
->pers_high
) {
54 if (!try_inc_mod_count(it
->module
))
56 read_unlock(&exec_domains_lock
);
59 read_unlock(&exec_domains_lock
);
61 /* Should never get this far. */
62 printk(KERN_ERR
"No execution domain for personality 0x%02lx\n", pers
);
66 int register_exec_domain(struct exec_domain
*it
)
68 struct exec_domain
*tmp
;
74 write_lock(&exec_domains_lock
);
75 for (tmp
=exec_domains
; tmp
; tmp
=tmp
->next
)
77 write_unlock(&exec_domains_lock
);
80 it
->next
= exec_domains
;
82 write_unlock(&exec_domains_lock
);
86 int unregister_exec_domain(struct exec_domain
*it
)
88 struct exec_domain
** tmp
;
91 write_lock(&exec_domains_lock
);
96 write_unlock(&exec_domains_lock
);
101 write_unlock(&exec_domains_lock
);
105 void __set_personality(unsigned long personality
)
107 struct exec_domain
*it
;
109 it
= lookup_exec_domain(personality
);
111 if (atomic_read(¤t
->fs
->count
) != 1) {
112 struct fs_struct
*new = copy_fs_struct(current
->fs
);
113 struct fs_struct
*old
;
121 task_unlock(current
);
125 * At that point we are guaranteed to be the sole owner of
128 current
->personality
= personality
;
129 current
->exec_domain
= it
;
131 put_exec_domain(current
->exec_domain
);
135 asmlinkage
long sys_personality(unsigned long personality
)
137 int ret
= current
->personality
;
138 if (personality
!= 0xffffffff) {
139 set_personality(personality
);
140 if (current
->personality
!= personality
)
146 int get_exec_domain_list(char * page
)
149 struct exec_domain
* e
;
151 read_lock(&exec_domains_lock
);
152 for (e
=exec_domains
; e
&& len
< PAGE_SIZE
- 80; e
=e
->next
)
153 len
+= sprintf(page
+len
, "%d-%d\t%-16s\t[%s]\n",
154 e
->pers_low
, e
->pers_high
, e
->name
,
155 e
->module
? e
->module
->name
: "kernel");
156 read_unlock(&exec_domains_lock
);