1*4c7a6a22Sryo /* $NetBSD: linux32_mod.c,v 1.15 2021/11/25 02:38:56 ryo Exp $ */
292ce8c6aSad
392ce8c6aSad /*-
492ce8c6aSad * Copyright (c) 2008 The NetBSD Foundation, Inc.
592ce8c6aSad * All rights reserved.
692ce8c6aSad *
792ce8c6aSad * This code is derived from software developed for The NetBSD Foundation
892ce8c6aSad * by Andrew Doran.
992ce8c6aSad *
1092ce8c6aSad * Redistribution and use in source and binary forms, with or without
1192ce8c6aSad * modification, are permitted provided that the following conditions
1292ce8c6aSad * are met:
1392ce8c6aSad * 1. Redistributions of source code must retain the above copyright
1492ce8c6aSad * notice, this list of conditions and the following disclaimer.
1592ce8c6aSad * 2. Redistributions in binary form must reproduce the above copyright
1692ce8c6aSad * notice, this list of conditions and the following disclaimer in the
1792ce8c6aSad * documentation and/or other materials provided with the distribution.
1892ce8c6aSad *
1992ce8c6aSad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2092ce8c6aSad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2192ce8c6aSad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2292ce8c6aSad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2392ce8c6aSad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2492ce8c6aSad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2592ce8c6aSad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2692ce8c6aSad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2792ce8c6aSad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2892ce8c6aSad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2992ce8c6aSad * POSSIBILITY OF SUCH DAMAGE.
3092ce8c6aSad */
3192ce8c6aSad
3292ce8c6aSad #include <sys/cdefs.h>
33*4c7a6a22Sryo __KERNEL_RCSID(0, "$NetBSD: linux32_mod.c,v 1.15 2021/11/25 02:38:56 ryo Exp $");
3492ce8c6aSad
3592ce8c6aSad #ifdef _KERNEL_OPT
3692ce8c6aSad #include "opt_execfmt.h"
3792ce8c6aSad #endif
3892ce8c6aSad
3992ce8c6aSad #ifndef ELFSIZE
4092ce8c6aSad #define ELFSIZE ARCH_ELFSIZE
4192ce8c6aSad #endif
4292ce8c6aSad
4392ce8c6aSad #include <sys/param.h>
4492ce8c6aSad #include <sys/module.h>
4592ce8c6aSad #include <sys/exec.h>
4692ce8c6aSad #include <sys/signalvar.h>
47252ca9c5Smaxv #include <sys/sysctl.h>
4892ce8c6aSad
4933fa5ccbSchs #include <compat/linux/common/linux_exec.h>
5033fa5ccbSchs
5192ce8c6aSad #include <compat/linux32/common/linux32_sysctl.h>
5292ce8c6aSad #include <compat/linux32/common/linux32_exec.h>
5392ce8c6aSad
5492ce8c6aSad #if defined(EXEC_ELF32)
551e89d6cdSpgoyette # define MD1 ",exec_elf32,compat_netbsd32,compat_netbsd32_sysvipc"
5692ce8c6aSad #else
5792ce8c6aSad # define MD1 ""
5892ce8c6aSad #endif
5992ce8c6aSad
60d91f98a8Spgoyette #define REQ1 "compat_linux,sysv_ipc,compat_sysv_50"
61d91f98a8Spgoyette #define REQ2 ",compat_netbsd32_50,compat_netbsd32_43"
62d91f98a8Spgoyette
63d91f98a8Spgoyette MODULE(MODULE_CLASS_EXEC, compat_linux32, REQ1 REQ2 MD1);
6492ce8c6aSad
6592ce8c6aSad static struct execsw linux32_execsw[] = {
6692ce8c6aSad #if defined(EXEC_ELF32)
6754b7adb1Schristos {
6854b7adb1Schristos .es_hdrsz = sizeof (Elf32_Ehdr),
6954b7adb1Schristos .es_makecmds = exec_elf32_makecmds,
7054b7adb1Schristos .u = {
7154b7adb1Schristos .elf_probe_func = linux32_elf32_probe,
7254b7adb1Schristos },
7354b7adb1Schristos .es_emul = &emul_linux32,
745848af8eSmaxv .es_prio = EXECSW_PRIO_ANY,
7554b7adb1Schristos .es_arglen = LINUX32_ELF_AUX_ARGSIZ,
7654b7adb1Schristos .es_copyargs = linux32_elf32_copyargs,
7754b7adb1Schristos .es_setregs = NULL,
7854b7adb1Schristos .es_coredump = coredump_elf32,
79*4c7a6a22Sryo .es_setup_stack = linux32_exec_setup_stack,
8054b7adb1Schristos },
8192ce8c6aSad #endif
8292ce8c6aSad };
8392ce8c6aSad
84c08407ddSjoerg int linux32_enabled = 1;
85252ca9c5Smaxv
86252ca9c5Smaxv int
linux32_sysctl_enable(SYSCTLFN_ARGS)87252ca9c5Smaxv linux32_sysctl_enable(SYSCTLFN_ARGS)
88252ca9c5Smaxv {
89252ca9c5Smaxv struct sysctlnode node;
90252ca9c5Smaxv int error, val;
91252ca9c5Smaxv
92252ca9c5Smaxv val = *(int *)rnode->sysctl_data;
93252ca9c5Smaxv
94252ca9c5Smaxv node = *rnode;
95252ca9c5Smaxv node.sysctl_data = &val;
96252ca9c5Smaxv
97252ca9c5Smaxv error = sysctl_lookup(SYSCTLFN_CALL(&node));
98252ca9c5Smaxv if (error != 0 || newp == NULL)
99252ca9c5Smaxv return error;
100252ca9c5Smaxv
101a2da047fSkre if (val == *(int *)rnode->sysctl_data)
102a2da047fSkre return 0;
103a2da047fSkre
104a2da047fSkre if (val == 1)
105252ca9c5Smaxv error = exec_add(linux32_execsw, __arraycount(linux32_execsw));
106a2da047fSkre else if (val == 0)
107a2da047fSkre error =
108a2da047fSkre exec_remove(linux32_execsw, __arraycount(linux32_execsw));
109a2da047fSkre else
110252ca9c5Smaxv error = EINVAL;
111a2da047fSkre
112252ca9c5Smaxv if (error)
113252ca9c5Smaxv return error;
114252ca9c5Smaxv
115252ca9c5Smaxv *(int *)rnode->sysctl_data = val;
116252ca9c5Smaxv
117252ca9c5Smaxv return 0;
118252ca9c5Smaxv }
119252ca9c5Smaxv
12092ce8c6aSad static int
compat_linux32_modcmd(modcmd_t cmd,void * arg)12192ce8c6aSad compat_linux32_modcmd(modcmd_t cmd, void *arg)
12292ce8c6aSad {
12392ce8c6aSad int error;
12492ce8c6aSad
12592ce8c6aSad switch (cmd) {
12692ce8c6aSad case MODULE_CMD_INIT:
127a2da047fSkre error = exec_add(linux32_execsw, __arraycount(linux32_execsw));
128a2da047fSkre return error;
12992ce8c6aSad
13092ce8c6aSad case MODULE_CMD_FINI:
131a2da047fSkre error =
132a2da047fSkre exec_remove(linux32_execsw, __arraycount(linux32_execsw));
133252ca9c5Smaxv if (error)
13492ce8c6aSad return error;
1354af030e5Spgoyette linux32_sysctl_fini();
136252ca9c5Smaxv return 0;
13792ce8c6aSad
13892ce8c6aSad default:
13992ce8c6aSad return ENOTTY;
14092ce8c6aSad }
14192ce8c6aSad }
142