1 1.19 pgoyette /* $NetBSD: linux32_sysctl.c,v 1.19 2020/03/21 16:28:56 pgoyette Exp $ */ 2 1.1 manu 3 1.1 manu /*- 4 1.1 manu * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. 5 1.1 manu * 6 1.1 manu * Redistribution and use in source and binary forms, with or without 7 1.1 manu * modification, are permitted provided that the following conditions 8 1.1 manu * are met: 9 1.1 manu * 1. Redistributions of source code must retain the above copyright 10 1.1 manu * notice, this list of conditions and the following disclaimer. 11 1.1 manu * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 manu * notice, this list of conditions and the following disclaimer in the 13 1.1 manu * documentation and/or other materials provided with the distribution. 14 1.1 manu * 3. All advertising materials mentioning features or use of this software 15 1.1 manu * must display the following acknowledgement: 16 1.1 manu * This product includes software developed by Emmanuel Dreyfus 17 1.1 manu * 4. The name of the author may not be used to endorse or promote 18 1.1 manu * products derived from this software without specific prior written 19 1.1 manu * permission. 20 1.1 manu * 21 1.1 manu * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' 22 1.1 manu * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 1.1 manu * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 1.1 manu * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 25 1.1 manu * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 1.1 manu * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 1.1 manu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 manu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 1.1 manu * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 1.1 manu * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 1.1 manu * POSSIBILITY OF SUCH DAMAGE. 32 1.1 manu */ 33 1.1 manu #include <sys/cdefs.h> 34 1.19 pgoyette __KERNEL_RCSID(0, "$NetBSD: linux32_sysctl.c,v 1.19 2020/03/21 16:28:56 pgoyette Exp $"); 35 1.1 manu 36 1.1 manu #include <sys/param.h> 37 1.1 manu #include <sys/systm.h> 38 1.1 manu #include <sys/errno.h> 39 1.1 manu #include <sys/proc.h> 40 1.1 manu #include <sys/mount.h> 41 1.1 manu #include <sys/sysctl.h> 42 1.1 manu #include <sys/syscallargs.h> 43 1.3 manu #include <sys/ktrace.h> 44 1.1 manu 45 1.1 manu #include <compat/netbsd32/netbsd32.h> 46 1.1 manu 47 1.1 manu #include <compat/linux/common/linux_types.h> 48 1.1 manu #include <compat/linux/common/linux_signal.h> 49 1.2 manu #include <compat/linux/common/linux_sysctl.h> 50 1.11 ad #include <compat/linux/common/linux_ipc.h> 51 1.11 ad #include <compat/linux/common/linux_sem.h> 52 1.1 manu #include <compat/linux/linux_syscallargs.h> 53 1.1 manu 54 1.1 manu #include <compat/linux32/common/linux32_types.h> 55 1.1 manu #include <compat/linux32/common/linux32_signal.h> 56 1.1 manu #include <compat/linux32/common/linux32_sysctl.h> 57 1.1 manu #include <compat/linux32/linux32_syscallargs.h> 58 1.1 manu 59 1.1 manu char linux32_sysname[128] = "Linux"; 60 1.14 chs char linux32_release[128] = "3.11.6"; 61 1.14 chs char linux32_version[128] = "#1 SMP PREEMPT Thu Oct 24 16:23:02 UTC 2013"; 62 1.1 manu 63 1.11 ad struct sysctlnode linux32_sysctl_root = { 64 1.11 ad .sysctl_flags = SYSCTL_VERSION| 65 1.11 ad CTLFLAG_ROOT|CTLTYPE_NODE|CTLFLAG_READWRITE, 66 1.11 ad .sysctl_num = 0, 67 1.11 ad .sysctl_name = "(linux32_root)", 68 1.16 martin .sysctl_size = sizeof(struct sysctlnode), 69 1.11 ad }; 70 1.11 ad 71 1.17 maxv extern int linux32_enabled; 72 1.1 manu 73 1.19 pgoyette /* 74 1.19 pgoyette * We need our own sysctllog here because we deal with two 75 1.19 pgoyette * separate sysctl trees; each clog is restricted to a 76 1.19 pgoyette * single tree. 77 1.19 pgoyette */ 78 1.19 pgoyette 79 1.19 pgoyette static struct sysctllog *linux32_clog; 80 1.19 pgoyette 81 1.19 pgoyette void 82 1.19 pgoyette linux32_sysctl_fini(void) 83 1.19 pgoyette { 84 1.19 pgoyette 85 1.19 pgoyette sysctl_teardown(&linux32_clog); 86 1.19 pgoyette sysctl_free(&linux32_sysctl_root); 87 1.19 pgoyette } 88 1.19 pgoyette 89 1.18 pgoyette SYSCTL_SETUP(linux32_sysctl_init, "linux32 emulation sysctls") 90 1.11 ad { 91 1.11 ad const struct sysctlnode *node = &linux32_sysctl_root; 92 1.11 ad 93 1.18 pgoyette sysctl_createv(clog, 0, NULL, NULL, 94 1.1 manu CTLFLAG_PERMANENT, 95 1.1 manu CTLTYPE_NODE, "linux32", 96 1.1 manu SYSCTL_DESCR("Linux 32 bit emulation settings"), 97 1.1 manu NULL, 0, NULL, 0, 98 1.1 manu CTL_EMUL, EMUL_LINUX32, CTL_EOL); 99 1.18 pgoyette sysctl_createv(clog, 0, NULL, NULL, 100 1.1 manu CTLFLAG_PERMANENT, 101 1.1 manu CTLTYPE_NODE, "kern", 102 1.1 manu SYSCTL_DESCR("Linux 32 bit kernel emulation settings"), 103 1.1 manu NULL, 0, NULL, 0, 104 1.1 manu CTL_EMUL, EMUL_LINUX32, EMUL_LINUX32_KERN, CTL_EOL); 105 1.1 manu 106 1.18 pgoyette sysctl_createv(clog, 0, NULL, NULL, 107 1.1 manu CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 108 1.1 manu CTLTYPE_STRING, "ostype", 109 1.1 manu SYSCTL_DESCR("Linux 32 bit operating system type"), 110 1.1 manu NULL, 0, linux32_sysname, sizeof(linux32_sysname), 111 1.1 manu CTL_EMUL, EMUL_LINUX32, EMUL_LINUX32_KERN, 112 1.1 manu EMUL_LINUX32_KERN_OSTYPE, CTL_EOL); 113 1.18 pgoyette sysctl_createv(clog, 0, NULL, NULL, 114 1.1 manu CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 115 1.1 manu CTLTYPE_STRING, "osrelease", 116 1.1 manu SYSCTL_DESCR("Linux 32 bit operating system release"), 117 1.1 manu NULL, 0, linux32_release, sizeof(linux32_release), 118 1.1 manu CTL_EMUL, EMUL_LINUX32, EMUL_LINUX32_KERN, 119 1.1 manu EMUL_LINUX32_KERN_OSRELEASE, CTL_EOL); 120 1.18 pgoyette sysctl_createv(clog, 0, NULL, NULL, 121 1.1 manu CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 122 1.1 manu CTLTYPE_STRING, "osversion", 123 1.1 manu SYSCTL_DESCR("Linux 32 bit operating system revision"), 124 1.1 manu NULL, 0, linux32_version, sizeof(linux32_version), 125 1.1 manu CTL_EMUL, EMUL_LINUX32, EMUL_LINUX32_KERN, 126 1.1 manu EMUL_LINUX32_KERN_VERSION, CTL_EOL); 127 1.18 pgoyette sysctl_createv(clog, 0, NULL, NULL, 128 1.17 maxv CTLFLAG_READWRITE, 129 1.17 maxv CTLTYPE_INT, "enabled", 130 1.17 maxv SYSCTL_DESCR("Linux 32 bit compat enabled."), 131 1.17 maxv linux32_sysctl_enable, 0, &linux32_enabled, 0, 132 1.17 maxv CTL_EMUL, EMUL_LINUX32, CTL_CREATE, CTL_EOL); 133 1.2 manu 134 1.19 pgoyette sysctl_createv(&linux32_clog, 0, &node, &node, 135 1.2 manu CTLFLAG_PERMANENT, 136 1.2 manu CTLTYPE_NODE, "kern", NULL, 137 1.2 manu NULL, 0, NULL, 0, 138 1.2 manu LINUX_CTL_KERN, CTL_EOL); 139 1.2 manu 140 1.19 pgoyette sysctl_createv(&linux32_clog, 0, &node, NULL, 141 1.2 manu CTLFLAG_PERMANENT, 142 1.2 manu CTLTYPE_STRING, "ostype", NULL, 143 1.2 manu NULL, 0, linux32_sysname, sizeof(linux32_sysname), 144 1.2 manu LINUX_KERN_OSTYPE, CTL_EOL); 145 1.19 pgoyette sysctl_createv(&linux32_clog, 0, &node, NULL, 146 1.2 manu CTLFLAG_PERMANENT, 147 1.2 manu CTLTYPE_STRING, "osrelease", NULL, 148 1.2 manu NULL, 0, linux32_release, sizeof(linux32_release), 149 1.2 manu LINUX_KERN_OSRELEASE, CTL_EOL); 150 1.19 pgoyette sysctl_createv(&linux32_clog, 0, &node, NULL, 151 1.2 manu CTLFLAG_PERMANENT, 152 1.2 manu CTLTYPE_STRING, "version", NULL, 153 1.2 manu NULL, 0, linux32_version, sizeof(linux32_version), 154 1.2 manu LINUX_KERN_VERSION, CTL_EOL); 155 1.2 manu 156 1.2 manu linux32_sysctl_root.sysctl_flags &= ~CTLFLAG_READWRITE; 157 1.2 manu } 158 1.1 manu 159 1.1 manu int 160 1.8 dsl linux32_sys___sysctl(struct lwp *l, const struct linux32_sys___sysctl_args *uap, register_t *retval) 161 1.1 manu { 162 1.8 dsl /* { 163 1.1 manu syscallarg(linux32___sysctlp_t) lsp; 164 1.8 dsl } */ 165 1.1 manu struct linux32_sysctl ls32; 166 1.2 manu int name[CTL_MAXNAME]; 167 1.2 manu size_t savelen; 168 1.2 manu netbsd32_size_t oldlen32; 169 1.2 manu size_t oldlen; 170 1.1 manu int error; 171 1.1 manu 172 1.2 manu /* 173 1.2 manu * Read sysctl arguments 174 1.2 manu */ 175 1.5 dsl if ((error = copyin(SCARG_P32(uap, lsp), &ls32, sizeof(ls32))) != 0) 176 1.1 manu return error; 177 1.1 manu 178 1.2 manu /* 179 1.2 manu * Read oldlen 180 1.2 manu */ 181 1.2 manu if (NETBSD32PTR64(ls32.oldlenp) != NULL) { 182 1.2 manu if ((error = copyin(NETBSD32PTR64(ls32.oldlenp), 183 1.2 manu &oldlen32, sizeof(oldlen32))) != 0) 184 1.2 manu return error; 185 1.2 manu } else { 186 1.2 manu oldlen32 = 0; 187 1.2 manu } 188 1.2 manu 189 1.2 manu savelen = (size_t)oldlen32; 190 1.2 manu 191 1.2 manu /* 192 1.2 manu * Sanity check nlen 193 1.2 manu */ 194 1.2 manu if ((ls32.nlen > CTL_MAXNAME) || (ls32.nlen < 1)) 195 1.12 njoly return ENOTDIR; 196 1.2 manu 197 1.2 manu /* 198 1.2 manu * Read the sysctl name 199 1.2 manu */ 200 1.2 manu if ((error = copyin(NETBSD32PTR64(ls32.name), &name, 201 1.2 manu ls32.nlen * sizeof(int))) != 0) 202 1.2 manu return error; 203 1.1 manu 204 1.6 ad ktrmib(name, ls32.nlen); 205 1.2 manu /* 206 1.2 manu * First try linux32 tree, then linux tree 207 1.2 manu */ 208 1.2 manu oldlen = (size_t)oldlen32; 209 1.9 ad sysctl_lock(NETBSD32PTR64(ls32.newval) != NULL); 210 1.2 manu error = sysctl_dispatch(name, ls32.nlen, 211 1.2 manu NETBSD32PTR64(ls32.oldval), &oldlen, 212 1.2 manu NETBSD32PTR64(ls32.newval), ls32.newlen, 213 1.2 manu name, l, &linux32_sysctl_root); 214 1.2 manu oldlen32 = (netbsd32_size_t)oldlen; 215 1.9 ad sysctl_unlock(); 216 1.2 manu 217 1.2 manu /* 218 1.2 manu * Check for oldlen overflow (not likely, but who knows...) 219 1.2 manu */ 220 1.2 manu if (oldlen != oldlen32) { 221 1.2 manu #ifdef DEBUG_LINUX 222 1.2 manu printf("%s: oldlen32 = %d, oldlen = %ld\n", 223 1.2 manu __func__, oldlen32, oldlen); 224 1.2 manu #endif 225 1.2 manu return EINVAL; 226 1.2 manu } 227 1.1 manu 228 1.2 manu /* 229 1.2 manu * set caller's oldlen, even if we got an error 230 1.2 manu */ 231 1.2 manu if (NETBSD32PTR64(ls32.oldlenp)) { 232 1.2 manu int nerror; 233 1.1 manu 234 1.2 manu nerror = copyout(&oldlen32, 235 1.2 manu NETBSD32PTR64(ls32.oldlenp), sizeof(oldlen32)); 236 1.1 manu 237 1.2 manu if (error == 0) 238 1.2 manu error = nerror; 239 1.2 manu } 240 1.1 manu 241 1.2 manu /* 242 1.2 manu * oldlen was too short 243 1.2 manu */ 244 1.2 manu if ((error == 0) && 245 1.2 manu (NETBSD32PTR64(ls32.oldval) != NULL) && 246 1.2 manu (savelen < oldlen32)) 247 1.2 manu error = ENOMEM; 248 1.1 manu 249 1.2 manu return error; 250 1.1 manu } 251