mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 15:39:42 -04:00
Merge branch 'exec_domain_rip_v2' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc
Pull exec domain removal from Richard Weinberger: "This series removes execution domain support from Linux. The idea behind exec domains was to support different ABIs. The feature was never complete nor stable. Let's rip it out and make the kernel signal handling code less complicated" * 'exec_domain_rip_v2' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc: (27 commits) arm64: Removed unused variable sparc: Fix execution domain removal Remove rest of exec domains. arch: Remove exec_domain from remaining archs arc: Remove signal translation and exec_domain xtensa: Remove signal translation and exec_domain xtensa: Autogenerate offsets in struct thread_info x86: Remove signal translation and exec_domain unicore32: Remove signal translation and exec_domain um: Remove signal translation and exec_domain tile: Remove signal translation and exec_domain sparc: Remove signal translation and exec_domain sh: Remove signal translation and exec_domain s390: Remove signal translation and exec_domain mn10300: Remove signal translation and exec_domain microblaze: Remove signal translation and exec_domain m68k: Remove signal translation and exec_domain m32r: Remove signal translation and exec_domain m32r: Autogenerate offsets in struct thread_info frv: Remove signal translation and exec_domain ...
This commit is contained in:
@@ -20,145 +20,10 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
||||
|
||||
static void default_handler(int, struct pt_regs *);
|
||||
|
||||
static struct exec_domain *exec_domains = &default_exec_domain;
|
||||
static DEFINE_RWLOCK(exec_domains_lock);
|
||||
|
||||
|
||||
static unsigned long ident_map[32] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31
|
||||
};
|
||||
|
||||
struct exec_domain default_exec_domain = {
|
||||
.name = "Linux", /* name */
|
||||
.handler = default_handler, /* lcall7 causes a seg fault. */
|
||||
.pers_low = 0, /* PER_LINUX personality. */
|
||||
.pers_high = 0, /* PER_LINUX personality. */
|
||||
.signal_map = ident_map, /* Identity map signals. */
|
||||
.signal_invmap = ident_map, /* - both ways. */
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
default_handler(int segment, struct pt_regs *regp)
|
||||
{
|
||||
set_personality(0);
|
||||
|
||||
if (current_thread_info()->exec_domain->handler != default_handler)
|
||||
current_thread_info()->exec_domain->handler(segment, regp);
|
||||
else
|
||||
send_sig(SIGSEGV, current, 1);
|
||||
}
|
||||
|
||||
static struct exec_domain *
|
||||
lookup_exec_domain(unsigned int personality)
|
||||
{
|
||||
unsigned int pers = personality(personality);
|
||||
struct exec_domain *ep;
|
||||
|
||||
read_lock(&exec_domains_lock);
|
||||
for (ep = exec_domains; ep; ep = ep->next) {
|
||||
if (pers >= ep->pers_low && pers <= ep->pers_high)
|
||||
if (try_module_get(ep->module))
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
read_unlock(&exec_domains_lock);
|
||||
request_module("personality-%d", pers);
|
||||
read_lock(&exec_domains_lock);
|
||||
|
||||
for (ep = exec_domains; ep; ep = ep->next) {
|
||||
if (pers >= ep->pers_low && pers <= ep->pers_high)
|
||||
if (try_module_get(ep->module))
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
ep = &default_exec_domain;
|
||||
out:
|
||||
read_unlock(&exec_domains_lock);
|
||||
return ep;
|
||||
}
|
||||
|
||||
int
|
||||
register_exec_domain(struct exec_domain *ep)
|
||||
{
|
||||
struct exec_domain *tmp;
|
||||
int err = -EBUSY;
|
||||
|
||||
if (ep == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (ep->next != NULL)
|
||||
return -EBUSY;
|
||||
|
||||
write_lock(&exec_domains_lock);
|
||||
for (tmp = exec_domains; tmp; tmp = tmp->next) {
|
||||
if (tmp == ep)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ep->next = exec_domains;
|
||||
exec_domains = ep;
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
write_unlock(&exec_domains_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(register_exec_domain);
|
||||
|
||||
int
|
||||
unregister_exec_domain(struct exec_domain *ep)
|
||||
{
|
||||
struct exec_domain **epp;
|
||||
|
||||
epp = &exec_domains;
|
||||
write_lock(&exec_domains_lock);
|
||||
for (epp = &exec_domains; *epp; epp = &(*epp)->next) {
|
||||
if (ep == *epp)
|
||||
goto unregister;
|
||||
}
|
||||
write_unlock(&exec_domains_lock);
|
||||
return -EINVAL;
|
||||
|
||||
unregister:
|
||||
*epp = ep->next;
|
||||
ep->next = NULL;
|
||||
write_unlock(&exec_domains_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_exec_domain);
|
||||
|
||||
int __set_personality(unsigned int personality)
|
||||
{
|
||||
struct exec_domain *oep = current_thread_info()->exec_domain;
|
||||
|
||||
current_thread_info()->exec_domain = lookup_exec_domain(personality);
|
||||
current->personality = personality;
|
||||
module_put(oep->module);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__set_personality);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static int execdomains_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct exec_domain *ep;
|
||||
|
||||
read_lock(&exec_domains_lock);
|
||||
for (ep = exec_domains; ep; ep = ep->next)
|
||||
seq_printf(m, "%d-%d\t%-16s\t[%s]\n",
|
||||
ep->pers_low, ep->pers_high, ep->name,
|
||||
module_name(ep->module));
|
||||
read_unlock(&exec_domains_lock);
|
||||
seq_puts(m, "0-0\tLinux \t[kernel]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -756,8 +756,6 @@ void do_exit(long code)
|
||||
|
||||
cgroup_exit(tsk);
|
||||
|
||||
module_put(task_thread_info(tsk)->exec_domain->module);
|
||||
|
||||
/*
|
||||
* FIXME: do that only when needed, using sched_exit tracepoint
|
||||
*/
|
||||
|
||||
@@ -1279,9 +1279,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
||||
if (nr_threads >= max_threads)
|
||||
goto bad_fork_cleanup_count;
|
||||
|
||||
if (!try_module_get(task_thread_info(p)->exec_domain->module))
|
||||
goto bad_fork_cleanup_count;
|
||||
|
||||
delayacct_tsk_init(p); /* Must remain after dup_task_struct() */
|
||||
p->flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER);
|
||||
p->flags |= PF_FORKNOEXEC;
|
||||
@@ -1590,7 +1587,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
||||
if (clone_flags & CLONE_THREAD)
|
||||
threadgroup_change_end(current);
|
||||
delayacct_tsk_free(p);
|
||||
module_put(task_thread_info(p)->exec_domain->module);
|
||||
bad_fork_cleanup_count:
|
||||
atomic_dec(&p->cred->user->processes);
|
||||
exit_creds(p);
|
||||
|
||||
Reference in New Issue
Block a user