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