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