15a1de9c2SJohn Baldwin /*-
25a1de9c2SJohn Baldwin * Copyright (c) 2022 University of Cambridge
35a1de9c2SJohn Baldwin *
45a1de9c2SJohn Baldwin * This software was developed by Ararat River Consulting, LLC under
55a1de9c2SJohn Baldwin * sponsorship from the University of Cambridge Computer Laboratory
65a1de9c2SJohn Baldwin * (Department of Computer Science and Technology) and Google, Inc.
75a1de9c2SJohn Baldwin *
85a1de9c2SJohn Baldwin * Redistribution and use in source and binary forms, with or without
95a1de9c2SJohn Baldwin * modification, are permitted provided that the following conditions
105a1de9c2SJohn Baldwin * are met:
115a1de9c2SJohn Baldwin * 1. Redistributions of source code must retain the above copyright
125a1de9c2SJohn Baldwin * notice, this list of conditions and the following disclaimer.
135a1de9c2SJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright
145a1de9c2SJohn Baldwin * notice, this list of conditions and the following disclaimer in the
155a1de9c2SJohn Baldwin * documentation and/or other materials provided with the distribution.
165a1de9c2SJohn Baldwin *
175a1de9c2SJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
185a1de9c2SJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
195a1de9c2SJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
205a1de9c2SJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
215a1de9c2SJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
225a1de9c2SJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
235a1de9c2SJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
245a1de9c2SJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
255a1de9c2SJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
265a1de9c2SJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
275a1de9c2SJohn Baldwin * SUCH DAMAGE.
285a1de9c2SJohn Baldwin */
295a1de9c2SJohn Baldwin
305a1de9c2SJohn Baldwin #include <sys/param.h>
315a1de9c2SJohn Baldwin #include <sys/module.h>
325a1de9c2SJohn Baldwin #include <errno.h>
335a1de9c2SJohn Baldwin #include <atf-c.h>
345a1de9c2SJohn Baldwin
355a1de9c2SJohn Baldwin ATF_TC_WITHOUT_HEAD(modfind);
ATF_TC_BODY(modfind,tc)365a1de9c2SJohn Baldwin ATF_TC_BODY(modfind, tc)
375a1de9c2SJohn Baldwin {
385a1de9c2SJohn Baldwin int modid;
395a1de9c2SJohn Baldwin
405a1de9c2SJohn Baldwin /* This module is present in sys/kern/subr_bus.c. */
415a1de9c2SJohn Baldwin modid = modfind("rootbus");
425a1de9c2SJohn Baldwin ATF_REQUIRE(modid > 0);
435a1de9c2SJohn Baldwin
445a1de9c2SJohn Baldwin modid = modfind("nonexistent_module");
455a1de9c2SJohn Baldwin ATF_REQUIRE(modid == -1);
46*18207579SJohn Baldwin ATF_REQUIRE(errno == ENOENT);
475a1de9c2SJohn Baldwin }
485a1de9c2SJohn Baldwin
495a1de9c2SJohn Baldwin ATF_TC_WITHOUT_HEAD(modnext);
ATF_TC_BODY(modnext,tc)505a1de9c2SJohn Baldwin ATF_TC_BODY(modnext, tc)
515a1de9c2SJohn Baldwin {
525a1de9c2SJohn Baldwin int modid;
535a1de9c2SJohn Baldwin
545a1de9c2SJohn Baldwin /* This assumes -1 is never used as a valid module id. */
555a1de9c2SJohn Baldwin modid = modnext(-1);
565a1de9c2SJohn Baldwin ATF_REQUIRE(modid == -1);
57*18207579SJohn Baldwin ATF_REQUIRE(errno == ENOENT);
585a1de9c2SJohn Baldwin
595a1de9c2SJohn Baldwin modid = modnext(0);
605a1de9c2SJohn Baldwin ATF_REQUIRE(modid > 0);
615a1de9c2SJohn Baldwin
625a1de9c2SJohn Baldwin for (;;) {
635a1de9c2SJohn Baldwin modid = modnext(modid);
645a1de9c2SJohn Baldwin ATF_REQUIRE(modid >= 0);
655a1de9c2SJohn Baldwin if (modid == 0)
665a1de9c2SJohn Baldwin break;
675a1de9c2SJohn Baldwin }
685a1de9c2SJohn Baldwin }
695a1de9c2SJohn Baldwin
705a1de9c2SJohn Baldwin ATF_TC_WITHOUT_HEAD(modfnext);
ATF_TC_BODY(modfnext,tc)715a1de9c2SJohn Baldwin ATF_TC_BODY(modfnext, tc)
725a1de9c2SJohn Baldwin {
735a1de9c2SJohn Baldwin int modid;
745a1de9c2SJohn Baldwin
755a1de9c2SJohn Baldwin /* This assumes -1 is never used as a valid module id. */
765a1de9c2SJohn Baldwin modid = modfnext(-1);
775a1de9c2SJohn Baldwin ATF_REQUIRE(modid == -1);
78*18207579SJohn Baldwin ATF_REQUIRE(errno == ENOENT);
795a1de9c2SJohn Baldwin
805a1de9c2SJohn Baldwin modid = modfnext(0);
815a1de9c2SJohn Baldwin ATF_REQUIRE(modid == -1);
82*18207579SJohn Baldwin ATF_REQUIRE(errno == ENOENT);
835a1de9c2SJohn Baldwin
845a1de9c2SJohn Baldwin modid = modnext(0);
855a1de9c2SJohn Baldwin ATF_REQUIRE(modid > 0);
865a1de9c2SJohn Baldwin
875a1de9c2SJohn Baldwin for (;;) {
885a1de9c2SJohn Baldwin modid = modfnext(modid);
895a1de9c2SJohn Baldwin ATF_REQUIRE(modid >= 0);
905a1de9c2SJohn Baldwin if (modid == 0)
915a1de9c2SJohn Baldwin break;
925a1de9c2SJohn Baldwin }
935a1de9c2SJohn Baldwin }
945a1de9c2SJohn Baldwin
955a1de9c2SJohn Baldwin ATF_TC_WITHOUT_HEAD(modstat);
ATF_TC_BODY(modstat,tc)965a1de9c2SJohn Baldwin ATF_TC_BODY(modstat, tc)
975a1de9c2SJohn Baldwin {
985a1de9c2SJohn Baldwin struct module_stat ms;
995a1de9c2SJohn Baldwin int modid;
1005a1de9c2SJohn Baldwin
1015a1de9c2SJohn Baldwin ms.version = sizeof(ms);
1025a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(0, &ms) == -1);
1035a1de9c2SJohn Baldwin ATF_REQUIRE(errno == ENOENT);
1045a1de9c2SJohn Baldwin
1055a1de9c2SJohn Baldwin modid = modnext(0);
1065a1de9c2SJohn Baldwin ATF_REQUIRE(modid > 0);
1075a1de9c2SJohn Baldwin
1085a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(modid, NULL) == -1);
1095a1de9c2SJohn Baldwin ATF_REQUIRE(errno == EFAULT);
1105a1de9c2SJohn Baldwin
1115a1de9c2SJohn Baldwin ms.version = 0;
1125a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(modid, &ms) == -1);
1135a1de9c2SJohn Baldwin ATF_REQUIRE(errno == EINVAL);
1145a1de9c2SJohn Baldwin
1155a1de9c2SJohn Baldwin ms.version = sizeof(ms);
1165a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(modid, &ms) == 0);
1175a1de9c2SJohn Baldwin ATF_REQUIRE(ms.id == modid);
1185a1de9c2SJohn Baldwin if (strnlen(ms.name, sizeof(ms.name)) < sizeof(ms.name))
1195a1de9c2SJohn Baldwin ATF_REQUIRE(modfind(ms.name) == modid);
1205a1de9c2SJohn Baldwin }
1215a1de9c2SJohn Baldwin
1225a1de9c2SJohn Baldwin ATF_TC_WITHOUT_HEAD(modstat_v1);
ATF_TC_BODY(modstat_v1,tc)1235a1de9c2SJohn Baldwin ATF_TC_BODY(modstat_v1, tc)
1245a1de9c2SJohn Baldwin {
1255a1de9c2SJohn Baldwin struct module_stat_v1 {
1265a1de9c2SJohn Baldwin int version;
1275a1de9c2SJohn Baldwin char name[32];
1285a1de9c2SJohn Baldwin int refs;
1295a1de9c2SJohn Baldwin int id;
1305a1de9c2SJohn Baldwin } ms;
1315a1de9c2SJohn Baldwin int modid;
1325a1de9c2SJohn Baldwin
1335a1de9c2SJohn Baldwin ms.version = sizeof(ms);
1345a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(0, (struct module_stat *)&ms) == -1);
1355a1de9c2SJohn Baldwin ATF_REQUIRE(errno == ENOENT);
1365a1de9c2SJohn Baldwin
1375a1de9c2SJohn Baldwin modid = modnext(0);
1385a1de9c2SJohn Baldwin ATF_REQUIRE(modid > 0);
1395a1de9c2SJohn Baldwin
1405a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(modid, NULL) == -1);
1415a1de9c2SJohn Baldwin ATF_REQUIRE(errno == EFAULT);
1425a1de9c2SJohn Baldwin
1435a1de9c2SJohn Baldwin ms.version = 0;
1445a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == -1);
1455a1de9c2SJohn Baldwin ATF_REQUIRE(errno == EINVAL);
1465a1de9c2SJohn Baldwin
1475a1de9c2SJohn Baldwin ms.version = sizeof(ms);
1485a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == 0);
1495a1de9c2SJohn Baldwin ATF_REQUIRE(ms.id == modid);
1505a1de9c2SJohn Baldwin if (strnlen(ms.name, sizeof(ms.name)) < sizeof(ms.name))
1515a1de9c2SJohn Baldwin ATF_REQUIRE(modfind(ms.name) == modid);
1525a1de9c2SJohn Baldwin }
1535a1de9c2SJohn Baldwin
1545a1de9c2SJohn Baldwin ATF_TC_WITHOUT_HEAD(modstat_v2);
ATF_TC_BODY(modstat_v2,tc)1555a1de9c2SJohn Baldwin ATF_TC_BODY(modstat_v2, tc)
1565a1de9c2SJohn Baldwin {
1575a1de9c2SJohn Baldwin struct module_stat_v2 {
1585a1de9c2SJohn Baldwin int version;
1595a1de9c2SJohn Baldwin char name[32];
1605a1de9c2SJohn Baldwin int refs;
1615a1de9c2SJohn Baldwin int id;
1625a1de9c2SJohn Baldwin modspecific_t data;
1635a1de9c2SJohn Baldwin } ms;
1645a1de9c2SJohn Baldwin int modid;
1655a1de9c2SJohn Baldwin
1665a1de9c2SJohn Baldwin ms.version = sizeof(ms);
1675a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(0, (struct module_stat *)&ms) == -1);
1685a1de9c2SJohn Baldwin ATF_REQUIRE(errno == ENOENT);
1695a1de9c2SJohn Baldwin
1705a1de9c2SJohn Baldwin modid = modnext(0);
1715a1de9c2SJohn Baldwin ATF_REQUIRE(modid > 0);
1725a1de9c2SJohn Baldwin
1735a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(modid, NULL) == -1);
1745a1de9c2SJohn Baldwin ATF_REQUIRE(errno == EFAULT);
1755a1de9c2SJohn Baldwin
1765a1de9c2SJohn Baldwin ms.version = 0;
1775a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == -1);
1785a1de9c2SJohn Baldwin ATF_REQUIRE(errno == EINVAL);
1795a1de9c2SJohn Baldwin
1805a1de9c2SJohn Baldwin ms.version = sizeof(ms);
1815a1de9c2SJohn Baldwin ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == 0);
1825a1de9c2SJohn Baldwin ATF_REQUIRE(ms.id == modid);
1835a1de9c2SJohn Baldwin if (strnlen(ms.name, sizeof(ms.name)) < sizeof(ms.name))
1845a1de9c2SJohn Baldwin ATF_REQUIRE(modfind(ms.name) == modid);
1855a1de9c2SJohn Baldwin }
1865a1de9c2SJohn Baldwin
ATF_TP_ADD_TCS(tp)1875a1de9c2SJohn Baldwin ATF_TP_ADD_TCS(tp)
1885a1de9c2SJohn Baldwin {
1895a1de9c2SJohn Baldwin ATF_TP_ADD_TC(tp, modfind);
1905a1de9c2SJohn Baldwin ATF_TP_ADD_TC(tp, modnext);
1915a1de9c2SJohn Baldwin ATF_TP_ADD_TC(tp, modfnext);
1925a1de9c2SJohn Baldwin ATF_TP_ADD_TC(tp, modstat);
1935a1de9c2SJohn Baldwin ATF_TP_ADD_TC(tp, modstat_v1);
1945a1de9c2SJohn Baldwin ATF_TP_ADD_TC(tp, modstat_v2);
1955a1de9c2SJohn Baldwin
1965a1de9c2SJohn Baldwin return (atf_no_error());
1975a1de9c2SJohn Baldwin }
198