1*eab38032Sriastradh /* $NetBSD: linux_mod.c,v 1.17 2024/10/01 16:41:29 riastradh 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*eab38032Sriastradh __KERNEL_RCSID(0, "$NetBSD: linux_mod.c,v 1.17 2024/10/01 16:41:29 riastradh 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> 47aef145ddSmaxv #include <sys/sysctl.h> 4892ce8c6aSad 498575c986Schristos #include <compat/linux/common/linux_inotify.h> 5092ce8c6aSad #include <compat/linux/common/linux_sysctl.h> 5192ce8c6aSad #include <compat/linux/common/linux_exec.h> 5292ce8c6aSad 5392ce8c6aSad #if defined(EXEC_ELF32) && ELFSIZE == 32 5492ce8c6aSad # define MD1 ",exec_elf32" 5592ce8c6aSad #else 5692ce8c6aSad # define MD1 "" 5792ce8c6aSad #endif 5892ce8c6aSad #if defined(EXEC_ELF64) 5992ce8c6aSad # define MD2 ",exec_elf64" 6092ce8c6aSad #else 6192ce8c6aSad # define MD2 "" 6292ce8c6aSad #endif 6392ce8c6aSad #if defined(EXEC_AOUT) 6492ce8c6aSad # define MD3 ",exec_aout" 6592ce8c6aSad #else 6692ce8c6aSad # define MD3 "" 6792ce8c6aSad #endif 6892ce8c6aSad 690124a941Schristos #define REQ1 "compat_ossaudio,sysv_ipc,mqueue,compat_util" 70d91f98a8Spgoyette #define REQ2 ",compat_50,compat_43" 71d91f98a8Spgoyette 72d91f98a8Spgoyette MODULE(MODULE_CLASS_EXEC, compat_linux, REQ1 REQ2 MD1 MD2 MD3); 7392ce8c6aSad 7492ce8c6aSad static struct execsw linux_execsw[] = { 7592ce8c6aSad #if defined(EXEC_ELF32) && ELFSIZE == 32 7654b7adb1Schristos { 7754b7adb1Schristos .es_hdrsz = sizeof (Elf32_Ehdr), 7854b7adb1Schristos .es_makecmds = exec_elf32_makecmds, 7954b7adb1Schristos .u = { 8054b7adb1Schristos .elf_probe_func = linux_elf32_probe, 8154b7adb1Schristos }, 8254b7adb1Schristos .es_emul = &emul_linux, 8354b7adb1Schristos .es_prio = EXECSW_PRIO_ANY, 8454b7adb1Schristos .es_arglen = LINUX_ELF_AUX_ARGSIZ, 8554b7adb1Schristos .es_copyargs = linux_elf32_copyargs, 8654b7adb1Schristos .es_setregs = NULL, 8754b7adb1Schristos .es_coredump = coredump_elf32, 8854b7adb1Schristos .es_setup_stack = linux_exec_setup_stack, 8954b7adb1Schristos }, 9092ce8c6aSad #elif defined(EXEC_ELF64) 9154b7adb1Schristos { 9254b7adb1Schristos .es_hdrsz = sizeof (Elf64_Ehdr), 9354b7adb1Schristos .es_makecmds = exec_elf64_makecmds, 9454b7adb1Schristos .u = { 9554b7adb1Schristos .elf_probe_func = linux_elf64_probe, 9654b7adb1Schristos }, 9754b7adb1Schristos .es_emul = &emul_linux, 9854b7adb1Schristos .es_prio = EXECSW_PRIO_ANY, 9954b7adb1Schristos .es_arglen = LINUX_ELF_AUX_ARGSIZ, 10054b7adb1Schristos .es_copyargs = linux_elf64_copyargs, 10154b7adb1Schristos .es_setregs = NULL, 10254b7adb1Schristos .es_coredump = coredump_elf64, 10354b7adb1Schristos .es_setup_stack = linux_exec_setup_stack, 10454b7adb1Schristos }, 10592ce8c6aSad #endif 10692ce8c6aSad #ifdef EXEC_AOUT 10754b7adb1Schristos { 10854b7adb1Schristos .es_hdrsz = LINUX_AOUT_HDR_SIZE, 10954b7adb1Schristos .es_makecmds = exec_linux_aout_makecmds, 11054b7adb1Schristos .u = { 11154b7adb1Schristos .elf_probe_func = NULL, 11254b7adb1Schristos }, 11354b7adb1Schristos .es_emul = &emul_linux, 11454b7adb1Schristos .es_prio = EXECSW_PRIO_LAST, 11554b7adb1Schristos .es_arglen = LINUX_AOUT_AUX_ARGSIZ, 11654b7adb1Schristos .es_copyargs = linux_aout_copyargs, 11754b7adb1Schristos .es_setregs = NULL, 11854b7adb1Schristos .es_coredump = coredump_netbsd, 11954b7adb1Schristos .es_setup_stack = linux_exec_setup_stack, 12054b7adb1Schristos }, 12192ce8c6aSad #endif 12292ce8c6aSad }; 12392ce8c6aSad 124c08407ddSjoerg int linux_enabled = 1; 125aef145ddSmaxv 126aef145ddSmaxv int 127aef145ddSmaxv linux_sysctl_enable(SYSCTLFN_ARGS) 128aef145ddSmaxv { 129aef145ddSmaxv struct sysctlnode node; 130aef145ddSmaxv int error, val; 131aef145ddSmaxv 132aef145ddSmaxv val = *(int *)rnode->sysctl_data; 133aef145ddSmaxv 134aef145ddSmaxv node = *rnode; 135aef145ddSmaxv node.sysctl_data = &val; 136aef145ddSmaxv 137aef145ddSmaxv error = sysctl_lookup(SYSCTLFN_CALL(&node)); 138aef145ddSmaxv if (error != 0 || newp == NULL) 139aef145ddSmaxv return error; 140aef145ddSmaxv 141a2da047fSkre if (val == *(int *)rnode->sysctl_data) 142a2da047fSkre return 0; 143a2da047fSkre 144a2da047fSkre if (val == 1) 145aef145ddSmaxv error = exec_add(linux_execsw, __arraycount(linux_execsw)); 146a2da047fSkre else if (val == 0) 147aef145ddSmaxv error = exec_remove(linux_execsw, __arraycount(linux_execsw)); 148a2da047fSkre else 149aef145ddSmaxv error = EINVAL; 150a2da047fSkre 151aef145ddSmaxv if (error) 152aef145ddSmaxv return error; 153aef145ddSmaxv 154aef145ddSmaxv *(int *)rnode->sysctl_data = val; 155aef145ddSmaxv 156aef145ddSmaxv return 0; 157aef145ddSmaxv } 158aef145ddSmaxv 15992ce8c6aSad static int 16092ce8c6aSad compat_linux_modcmd(modcmd_t cmd, void *arg) 16192ce8c6aSad { 16292ce8c6aSad int error; 16392ce8c6aSad 16492ce8c6aSad switch (cmd) { 16592ce8c6aSad case MODULE_CMD_INIT: 1668575c986Schristos error = linux_inotify_init(); 1678575c986Schristos if (error != 0) 1688575c986Schristos return error; 169a2da047fSkre error = exec_add(linux_execsw, __arraycount(linux_execsw)); 1708575c986Schristos if (error) 1718575c986Schristos linux_inotify_fini(); 172a2da047fSkre return error; 17392ce8c6aSad 17492ce8c6aSad case MODULE_CMD_FINI: 175aef145ddSmaxv error = exec_remove(linux_execsw, __arraycount(linux_execsw)); 176aef145ddSmaxv if (error) 177aef145ddSmaxv return error; 1784af030e5Spgoyette linux_sysctl_fini(); 1798575c986Schristos linux_inotify_fini(); 180aef145ddSmaxv return 0; 18192ce8c6aSad 18292ce8c6aSad default: 18392ce8c6aSad return ENOTTY; 18492ce8c6aSad } 18592ce8c6aSad } 186