1 1.12 dholland /* $NetBSD: subr_kobj_vfs.c,v 1.12 2021/06/29 22:40:53 dholland Exp $ */ 2 1.1 pooka 3 1.1 pooka /*- 4 1.1 pooka * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 1.1 pooka * All rights reserved. 6 1.1 pooka * 7 1.1 pooka * This code is derived from software developed for The NetBSD Foundation 8 1.1 pooka * by Andrew Doran. 9 1.1 pooka * 10 1.1 pooka * Redistribution and use in source and binary forms, with or without 11 1.1 pooka * modification, are permitted provided that the following conditions 12 1.1 pooka * are met: 13 1.1 pooka * 1. Redistributions of source code must retain the above copyright 14 1.1 pooka * notice, this list of conditions and the following disclaimer. 15 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 pooka * notice, this list of conditions and the following disclaimer in the 17 1.1 pooka * documentation and/or other materials provided with the distribution. 18 1.1 pooka * 19 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 pooka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 pooka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 pooka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 pooka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 pooka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 pooka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 pooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 pooka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 pooka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 pooka * POSSIBILITY OF SUCH DAMAGE. 30 1.1 pooka */ 31 1.1 pooka 32 1.1 pooka /*- 33 1.1 pooka * Copyright (c) 1998-2000 Doug Rabson 34 1.1 pooka * Copyright (c) 2004 Peter Wemm 35 1.1 pooka * All rights reserved. 36 1.1 pooka * 37 1.1 pooka * Redistribution and use in source and binary forms, with or without 38 1.1 pooka * modification, are permitted provided that the following conditions 39 1.1 pooka * are met: 40 1.1 pooka * 1. Redistributions of source code must retain the above copyright 41 1.1 pooka * notice, this list of conditions and the following disclaimer. 42 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 43 1.1 pooka * notice, this list of conditions and the following disclaimer in the 44 1.1 pooka * documentation and/or other materials provided with the distribution. 45 1.1 pooka * 46 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 47 1.1 pooka * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 1.1 pooka * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 1.1 pooka * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 50 1.1 pooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 1.1 pooka * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 1.1 pooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 1.1 pooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 1.1 pooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 1.1 pooka * SUCH DAMAGE. 57 1.1 pooka */ 58 1.1 pooka 59 1.1 pooka /* 60 1.1 pooka * Kernel loader vfs routines. 61 1.1 pooka */ 62 1.1 pooka 63 1.1 pooka #include <sys/kobj_impl.h> 64 1.8 pooka 65 1.8 pooka #ifdef _KERNEL_OPT 66 1.1 pooka #include "opt_modular.h" 67 1.8 pooka #endif 68 1.1 pooka 69 1.1 pooka #ifdef MODULAR 70 1.1 pooka 71 1.1 pooka #include <sys/param.h> 72 1.1 pooka #include <sys/fcntl.h> 73 1.1 pooka #include <sys/module.h> 74 1.1 pooka #include <sys/namei.h> 75 1.1 pooka #include <sys/vnode.h> 76 1.1 pooka 77 1.1 pooka #include <sys/cdefs.h> 78 1.12 dholland __KERNEL_RCSID(0, "$NetBSD: subr_kobj_vfs.c,v 1.12 2021/06/29 22:40:53 dholland Exp $"); 79 1.1 pooka 80 1.1 pooka static void 81 1.2 pooka kobj_close_vfs(kobj_t ko) 82 1.1 pooka { 83 1.1 pooka 84 1.3 hannken VOP_UNLOCK(ko->ko_source); 85 1.1 pooka vn_close(ko->ko_source, FREAD, kauth_cred_get()); 86 1.1 pooka } 87 1.1 pooka 88 1.1 pooka /* 89 1.1 pooka * kobj_read: 90 1.1 pooka * 91 1.1 pooka * Utility function: read from the object. 92 1.1 pooka */ 93 1.1 pooka static int 94 1.2 pooka kobj_read_vfs(kobj_t ko, void **basep, size_t size, off_t off, 95 1.1 pooka bool allocate) 96 1.1 pooka { 97 1.1 pooka size_t resid; 98 1.1 pooka void *base; 99 1.1 pooka int error; 100 1.1 pooka 101 1.1 pooka KASSERT(ko->ko_source != NULL); 102 1.1 pooka 103 1.1 pooka if (allocate) { 104 1.1 pooka base = kmem_alloc(size, KM_SLEEP); 105 1.1 pooka } else { 106 1.1 pooka base = *basep; 107 1.9 maxv #ifdef DIAGNOSTIC 108 1.9 maxv bool ok = false; 109 1.9 maxv if ((uintptr_t)base >= (uintptr_t)ko->ko_text_address && 110 1.9 maxv (uintptr_t)base + size <= 111 1.9 maxv (uintptr_t)ko->ko_text_address + ko->ko_text_size) 112 1.9 maxv ok = true; 113 1.9 maxv if ((uintptr_t)base >= (uintptr_t)ko->ko_data_address && 114 1.9 maxv (uintptr_t)base + size <= 115 1.9 maxv (uintptr_t)ko->ko_data_address + ko->ko_data_size) 116 1.9 maxv ok = true; 117 1.10 maxv if ((uintptr_t)base >= (uintptr_t)ko->ko_rodata_address && 118 1.10 maxv (uintptr_t)base + size <= 119 1.10 maxv (uintptr_t)ko->ko_rodata_address + ko->ko_rodata_size) 120 1.10 maxv ok = true; 121 1.9 maxv if (!ok) 122 1.9 maxv panic("kobj_read_vfs: not in a dedicated segment"); 123 1.9 maxv #endif 124 1.1 pooka } 125 1.1 pooka 126 1.1 pooka error = vn_rdwr(UIO_READ, ko->ko_source, base, size, off, 127 1.1 pooka UIO_SYSSPACE, IO_NODELOCKED, curlwp->l_cred, &resid, 128 1.1 pooka curlwp); 129 1.1 pooka 130 1.1 pooka if (error == 0 && resid != 0) { 131 1.1 pooka error = EINVAL; 132 1.1 pooka } 133 1.1 pooka 134 1.1 pooka if (allocate && error != 0) { 135 1.1 pooka kmem_free(base, size); 136 1.1 pooka base = NULL; 137 1.1 pooka } 138 1.1 pooka 139 1.1 pooka if (allocate) 140 1.1 pooka *basep = base; 141 1.1 pooka 142 1.1 pooka return error; 143 1.1 pooka } 144 1.1 pooka 145 1.1 pooka /* 146 1.2 pooka * kobj_load_vfs: 147 1.1 pooka * 148 1.1 pooka * Load an object located in the file system. 149 1.1 pooka */ 150 1.1 pooka int 151 1.2 pooka kobj_load_vfs(kobj_t *kop, const char *path, const bool nochroot) 152 1.1 pooka { 153 1.4 dholland struct pathbuf *pb; 154 1.12 dholland struct vnode *vp; 155 1.1 pooka int error; 156 1.1 pooka kobj_t ko; 157 1.1 pooka 158 1.5 mbalmer KASSERT(path != NULL); 159 1.5 mbalmer if (strchr(path, '/') == NULL) 160 1.5 mbalmer return ENOENT; 161 1.5 mbalmer 162 1.1 pooka ko = kmem_zalloc(sizeof(*ko), KM_SLEEP); 163 1.4 dholland pb = pathbuf_create(path); 164 1.4 dholland if (pb == NULL) { 165 1.4 dholland kmem_free(ko, sizeof(*ko)); 166 1.4 dholland return ENOMEM; 167 1.4 dholland } 168 1.4 dholland 169 1.12 dholland error = vn_open(NULL, pb, (nochroot ? NOCHROOT : 0), FREAD, 0, 170 1.12 dholland &vp, NULL, NULL); 171 1.1 pooka 172 1.1 pooka if (error != 0) { 173 1.4 dholland pathbuf_destroy(pb); 174 1.1 pooka kmem_free(ko, sizeof(*ko)); 175 1.1 pooka return error; 176 1.1 pooka } 177 1.1 pooka 178 1.1 pooka ko->ko_type = KT_VNODE; 179 1.6 christos kobj_setname(ko, path); 180 1.12 dholland ko->ko_source = vp; 181 1.2 pooka ko->ko_read = kobj_read_vfs; 182 1.2 pooka ko->ko_close = kobj_close_vfs; 183 1.4 dholland pathbuf_destroy(pb); 184 1.1 pooka 185 1.1 pooka *kop = ko; 186 1.1 pooka return kobj_load(ko); 187 1.1 pooka } 188 1.1 pooka 189 1.1 pooka #else /* MODULAR */ 190 1.1 pooka 191 1.1 pooka int 192 1.2 pooka kobj_load_vfs(kobj_t *kop, const char *path, const bool nochroot) 193 1.1 pooka { 194 1.1 pooka 195 1.1 pooka return ENOSYS; 196 1.1 pooka } 197 1.1 pooka 198 1.1 pooka #endif 199