1 /*- 2 * Copyright (c) 2022 University of Cambridge 3 * 4 * This software was developed by Ararat River Consulting, LLC under 5 * sponsorship from the University of Cambridge Computer Laboratory 6 * (Department of Computer Science and Technology) and Google, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/param.h> 31 #include <sys/module.h> 32 #include <errno.h> 33 #include <atf-c.h> 34 35 ATF_TC_WITHOUT_HEAD(modfind); 36 ATF_TC_BODY(modfind, tc) 37 { 38 int modid; 39 40 /* This module is present in sys/kern/subr_bus.c. */ 41 modid = modfind("rootbus"); 42 ATF_REQUIRE(modid > 0); 43 44 modid = modfind("nonexistent_module"); 45 ATF_REQUIRE(modid == -1); 46 ATF_REQUIRE(errno == ENOENT); 47 } 48 49 ATF_TC_WITHOUT_HEAD(modnext); 50 ATF_TC_BODY(modnext, tc) 51 { 52 int modid; 53 54 /* This assumes -1 is never used as a valid module id. */ 55 modid = modnext(-1); 56 ATF_REQUIRE(modid == -1); 57 ATF_REQUIRE(errno == ENOENT); 58 59 modid = modnext(0); 60 ATF_REQUIRE(modid > 0); 61 62 for (;;) { 63 modid = modnext(modid); 64 ATF_REQUIRE(modid >= 0); 65 if (modid == 0) 66 break; 67 } 68 } 69 70 ATF_TC_WITHOUT_HEAD(modfnext); 71 ATF_TC_BODY(modfnext, tc) 72 { 73 int modid; 74 75 /* This assumes -1 is never used as a valid module id. */ 76 modid = modfnext(-1); 77 ATF_REQUIRE(modid == -1); 78 ATF_REQUIRE(errno == ENOENT); 79 80 modid = modfnext(0); 81 ATF_REQUIRE(modid == -1); 82 ATF_REQUIRE(errno == ENOENT); 83 84 modid = modnext(0); 85 ATF_REQUIRE(modid > 0); 86 87 for (;;) { 88 modid = modfnext(modid); 89 ATF_REQUIRE(modid >= 0); 90 if (modid == 0) 91 break; 92 } 93 } 94 95 ATF_TC_WITHOUT_HEAD(modstat); 96 ATF_TC_BODY(modstat, tc) 97 { 98 struct module_stat ms; 99 int modid; 100 101 ms.version = sizeof(ms); 102 ATF_REQUIRE(modstat(0, &ms) == -1); 103 ATF_REQUIRE(errno == ENOENT); 104 105 modid = modnext(0); 106 ATF_REQUIRE(modid > 0); 107 108 ATF_REQUIRE(modstat(modid, NULL) == -1); 109 ATF_REQUIRE(errno == EFAULT); 110 111 ms.version = 0; 112 ATF_REQUIRE(modstat(modid, &ms) == -1); 113 ATF_REQUIRE(errno == EINVAL); 114 115 ms.version = sizeof(ms); 116 ATF_REQUIRE(modstat(modid, &ms) == 0); 117 ATF_REQUIRE(ms.id == modid); 118 if (strnlen(ms.name, sizeof(ms.name)) < sizeof(ms.name)) 119 ATF_REQUIRE(modfind(ms.name) == modid); 120 } 121 122 ATF_TC_WITHOUT_HEAD(modstat_v1); 123 ATF_TC_BODY(modstat_v1, tc) 124 { 125 struct module_stat_v1 { 126 int version; 127 char name[32]; 128 int refs; 129 int id; 130 } ms; 131 int modid; 132 133 ms.version = sizeof(ms); 134 ATF_REQUIRE(modstat(0, (struct module_stat *)&ms) == -1); 135 ATF_REQUIRE(errno == ENOENT); 136 137 modid = modnext(0); 138 ATF_REQUIRE(modid > 0); 139 140 ATF_REQUIRE(modstat(modid, NULL) == -1); 141 ATF_REQUIRE(errno == EFAULT); 142 143 ms.version = 0; 144 ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == -1); 145 ATF_REQUIRE(errno == EINVAL); 146 147 ms.version = sizeof(ms); 148 ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == 0); 149 ATF_REQUIRE(ms.id == modid); 150 if (strnlen(ms.name, sizeof(ms.name)) < sizeof(ms.name)) 151 ATF_REQUIRE(modfind(ms.name) == modid); 152 } 153 154 ATF_TC_WITHOUT_HEAD(modstat_v2); 155 ATF_TC_BODY(modstat_v2, tc) 156 { 157 struct module_stat_v2 { 158 int version; 159 char name[32]; 160 int refs; 161 int id; 162 modspecific_t data; 163 } ms; 164 int modid; 165 166 ms.version = sizeof(ms); 167 ATF_REQUIRE(modstat(0, (struct module_stat *)&ms) == -1); 168 ATF_REQUIRE(errno == ENOENT); 169 170 modid = modnext(0); 171 ATF_REQUIRE(modid > 0); 172 173 ATF_REQUIRE(modstat(modid, NULL) == -1); 174 ATF_REQUIRE(errno == EFAULT); 175 176 ms.version = 0; 177 ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == -1); 178 ATF_REQUIRE(errno == EINVAL); 179 180 ms.version = sizeof(ms); 181 ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == 0); 182 ATF_REQUIRE(ms.id == modid); 183 if (strnlen(ms.name, sizeof(ms.name)) < sizeof(ms.name)) 184 ATF_REQUIRE(modfind(ms.name) == modid); 185 } 186 187 ATF_TP_ADD_TCS(tp) 188 { 189 ATF_TP_ADD_TC(tp, modfind); 190 ATF_TP_ADD_TC(tp, modnext); 191 ATF_TP_ADD_TC(tp, modfnext); 192 ATF_TP_ADD_TC(tp, modstat); 193 ATF_TP_ADD_TC(tp, modstat_v1); 194 ATF_TP_ADD_TC(tp, modstat_v2); 195 196 return (atf_no_error()); 197 } 198