From nobody Sun Jun 14 23:47:33 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gdqgG4Yx1z6hl8w for ; Sun, 14 Jun 2026 23:47:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gdqgG3gTyz3sHK for ; Sun, 14 Jun 2026 23:47:38 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1781480858; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=oVYEqttZOCj5KKMTZio8MKlGrM6Lm7N89ttKmhiwtVg=; b=JM7pszprpy+FIEbonVjECX+RtYVn1l9xAkx9CoOXKzwJfpQlrPivHgbeTZY64FPBpiyndV 7a3wDS2Wp5v9TxfDBlmQbqwfahBQwJlHNHYOWGnncD64D0Wv+3nq/GZ9Q8d/mBRyJl+IZX J7dNJL8LePopfis6qunyj7tx9YqcajnjIMm21Zlu6iEHtMNiDwW38g3KaDGi53oW9iwgKM v1mV2Kij9PRYsxk0cHrR6lBN14AXZ9EcvmGkLy6LdZUgGrJTdS3mDL2/a2ssqsDNfnYFwA nZNZng8L1pA09h9sbHokbRnLGJWmW4Rlkgx4L/MXIeei4Vqbd/MEb1J90h8tng== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1781480858; a=rsa-sha256; cv=none; b=LIVcwBsM+7vswCjgcZgQtgsYyjVQiCJ8Pc43Lf6+/Z9D4xuSn2h6uwXTeGH30SmD+ocDKE 5kMvF/u4wtavHGq4J8PwIc0ZpBvzNkoIfUimBXV77Kx6b2Ohw7cPo43QI4BNqBkAvz5L+k xAb2yBK+zDRe55dCfawdfjPqay6oLC4OV8KF5GHeZ74D2ewGko601XdzaNJKCDDqSIEi5R caqME4rZA4kRVtAiOrXtm2EJif0N8ZsOVTc98476hQ34HCqzVggQMUXf+7fXuFsX8re+oN r3gJpC63qZn8uzGmVGR/yCX0A80lHzpvylPUscUUlZK4TIBuBb0UuTd8vbXRgA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1781480858; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=oVYEqttZOCj5KKMTZio8MKlGrM6Lm7N89ttKmhiwtVg=; b=QCr1a+1rX0yXUj9+KO1GDirozSS+gf0W8iFsAeUpgKyJS86A/gl+aqrkK3wtedC+pWAdAt KAsCn8Wm2HdlKTRDDine2mGPTbTeK+ND9r2svSjUbidVQgUKZlOl5ypXJvKvkg3URcBHS1 FqqLY/qcedhLU4KRK9JKkKqa5hWknBOeP4KhlRX6VYHEJSyF4AkBVnajz34Pi3gs4ncLU9 JI3TV8N1J9L/3fBw+cYlBgPyqnjH2fOiFbRl5OcRfHb/IbPa19dq3oJF/xzL9oUOMW/n4m LaBcddfEHXZHN1ngNECdUzf8M08ANoQLoybdE+fUkNXKkbdVGQwrhV2egv9BWw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gdqgG3G9hzVd6 for ; Sun, 14 Jun 2026 23:47:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 18be4 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 14 Jun 2026 23:47:33 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Jim Huang Chen From: Ed Maste Subject: git: db887713de2b - main - kldload: Improve error handling List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: emaste X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: db887713de2bf5c77494220a9e0ddfa7d4290155 Auto-Submitted: auto-generated Date: Sun, 14 Jun 2026 23:47:33 +0000 Message-Id: <6a2f3d95.18be4.3b5353a4@gitrepo.freebsd.org> The branch main has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=db887713de2bf5c77494220a9e0ddfa7d4290155 commit db887713de2bf5c77494220a9e0ddfa7d4290155 Author: Jim Huang Chen AuthorDate: 2026-05-25 16:23:29 +0000 Commit: Ed Maste CommitDate: 2026-06-14 23:45:50 +0000 kldload: Improve error handling Address a failure in linker_load_module (sys/kern/kern_linker.c) to verify that an already-loaded module matches the version requirement, which caused the method to return the error (EEXIST). This was then propagated back up to kldload, which incorrectly printed that the module had already been loaded. Add a lookup to modlist_lookup2 to distinguish between the two cases: - A module is already loaded that is of the correct version, so the error EEXIST should be returned - An already-loaded module is of the incorrect version, so the error ENOEXEC is returned (changed from ENOENT) Reviewed by: imp, kib Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D57002 --- lib/libc/gen/exterr_cat_filenames.h | 1 + sbin/kldload/kldload.c | 17 ++++---- sys/kern/kern_linker.c | 83 ++++++++++++++++++++++++------------- sys/sys/exterr_cat.h | 1 + 4 files changed, 65 insertions(+), 37 deletions(-) diff --git a/lib/libc/gen/exterr_cat_filenames.h b/lib/libc/gen/exterr_cat_filenames.h index be65c1990af5..90e231879ccd 100644 --- a/lib/libc/gen/exterr_cat_filenames.h +++ b/lib/libc/gen/exterr_cat_filenames.h @@ -12,6 +12,7 @@ [EXTERR_CAT_FILEDESC] = "kern/kern_descrip.c", [EXTERR_CAT_PROCEXIT] = "kern/kern_exit.c", [EXTERR_CAT_FORK] = "kern/kern_fork.c", + [EXTERR_CAT_LINKER] = "kern/kern_linker.c", [EXTERR_CAT_GENIO] = "kern/sys_generic.c", [EXTERR_CAT_VFSBIO] = "kern/vfs_bio.c", [EXTERR_CAT_INOTIFY] = "kern/vfs_inotify.c", diff --git a/sbin/kldload/kldload.c b/sbin/kldload/kldload.c index 82469a2d40f3..79c28e19ed5d 100644 --- a/sbin/kldload/kldload.c +++ b/sbin/kldload/kldload.c @@ -95,8 +95,9 @@ path_check(const char *kldname, int quiet) if (sb.st_dev != dev || sb.st_ino != ino) { if (!quiet) - warnx("%s will be loaded from %s, not the " - "current directory", kldname, element); + warnx( +"%s will be loaded from %s, not the current directory", + kldname, element); break; } else if (sb.st_dev == dev && sb.st_ino == ino) break; @@ -171,15 +172,13 @@ main(int argc, char** argv) if (!quiet) { switch (errno) { case EEXIST: - warnx("can't load %s: module " - "already loaded or " - "in kernel", argv[0]); + warnx( +"can't load %s: module already loaded or in kernel", argv[0]); break; case ENOEXEC: - warnx("an error occurred while " - "loading module %s. " - "Please check dmesg(8) for " - "more details.", argv[0]); + warnx( +"an error occurred while loading module %s. Please check dmesg(8) for more details.", + argv[0]); break; default: warn("can't load %s", argv[0]); diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 9559b5233a3e..770374449a17 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -32,10 +32,12 @@ #include "opt_hwpmc_hooks.h" #include "opt_hwt_hooks.h" +#define EXTERR_CATEGORY EXTERR_CAT_LINKER #include #include #include #include +#include #include #include #include @@ -455,13 +457,14 @@ linker_load_file(const char *filename, linker_file_t *result) /* Refuse to load modules if securelevel raised */ if (prison0.pr_securelevel > 0) - return (EPERM); + return (EXTERROR(EPERM, "security level %jd", + prison0.pr_securelevel)); sx_assert(&kld_sx, SA_XLOCKED); lf = linker_find_file_by_name(filename); if (lf) { - KLD_DPF(FILE, ("linker_load_file: file %s is already loaded," - " incrementing refs\n", filename)); + KLD_DPF(FILE, +("linker_load_file: file %s is already loaded, incrementing refs\n", filename)); *result = lf; lf->refs++; return (0); @@ -508,7 +511,7 @@ linker_load_file(const char *filename, linker_file_t *result) */ if (modules && TAILQ_EMPTY(&lf->modules)) { linker_file_unload(lf, LINKER_UNLOAD_FORCE); - return (ENOEXEC); + return (EXTERROR(ENOEXEC, "no modules loaded")); } linker_file_enable_sysctls(lf); @@ -535,17 +538,19 @@ linker_load_file(const char *filename, linker_file_t *result) __func__, filename); /* - * Format not recognized or otherwise unloadable. - * When loading a module that is statically built into - * the kernel EEXIST percolates back up as the return - * value. Preserve this so that apps like sysinstall - * can recognize this special case and not post bogus - * dialog boxes. + * Format not recognized, version incompatible, or + * otherwise unloadable. When loading a module that is + * statically built into the kernel EEXIST percolates + * back up as the return value. Preserve this so that + * apps like sysinstall can recognize this special case + * and not post bogus dialog boxes. */ if (error != EEXIST) - error = ENOEXEC; + error = EXTERROR(ENOEXEC, + "module format or version error"); } else - error = ENOENT; /* Nothing found */ + error = EXTERROR(ENOENT, "kld file not found"); + /* Nothing found */ return (error); } @@ -2249,6 +2254,7 @@ linker_load_module(const char *kldname, const char *modname, struct linker_file *parent, const struct mod_depend *verinfo, struct linker_file **lfpp) { + modlist_t mod; linker_file_t lfdep; const char *filename; char *pathname; @@ -2259,16 +2265,15 @@ linker_load_module(const char *kldname, const char *modname, /* * We have to load KLD */ - KASSERT(verinfo == NULL, ("linker_load_module: verinfo" - " is not NULL")); + MPASS(verinfo == NULL); if (!linker_root_mounted()) - return (ENXIO); + return (EXTERROR(ENXIO, "root not yet mounted")); pathname = linker_search_kld(kldname); } else { if (modlist_lookup2(modname, verinfo) != NULL) - return (EEXIST); + return (EXTERROR(EEXIST, "module already loaded")); if (!linker_root_mounted()) - return (ENXIO); + return (EXTERROR(ENXIO, "root not yet mounted")); if (kldname != NULL) pathname = strdup(kldname, M_LINKER); else @@ -2279,7 +2284,7 @@ linker_load_module(const char *kldname, const char *modname, strlen(modname), verinfo); } if (pathname == NULL) - return (ENOENT); + return (EXTERROR(ENOENT, "kld file not found")); /* * Can't load more than one file with the same basename XXX: @@ -2288,16 +2293,36 @@ linker_load_module(const char *kldname, const char *modname, * provide different versions of the same modules. */ filename = linker_basename(pathname); - if (linker_find_file_by_name(filename)) - error = EEXIST; - else do { + lfdep = linker_find_file_by_name(filename); + if (lfdep) { + mod = modlist_lookup(modname, 0); + MPASS(mod != NULL); + + if (modname && verinfo && + modlist_lookup2(modname, verinfo) == NULL) { + /* + * Desired module is already loaded, but the correct + * version does not exist. + */ + error = EXTERROR(ENOEXEC, + "incompatible module version %jd already loaded", + mod->version); + } else { + error = EXTERROR(EEXIST, + "module version %jd already loaded", + mod->version); + } + } else do { error = linker_load_file(pathname, &lfdep); if (error) break; if (modname && verinfo && modlist_lookup2(modname, verinfo) == NULL) { + mod = modlist_lookup(modname, 0); + error = EXTERROR(ENOEXEC, + "incompatible module version %jd already loaded", + mod->version); linker_file_unload(lfdep, LINKER_UNLOAD_FORCE); - error = ENOENT; break; } if (parent) @@ -2343,10 +2368,11 @@ linker_load_dependencies(linker_file_t lf) ver = ((const struct mod_version *)mp->md_data)->mv_version; mod = modlist_lookup(modname, ver); if (mod != NULL) { - printf("interface %s.%d already present in the KLD" - " '%s'!\n", modname, ver, - mod->container->filename); - return (EEXIST); + printf( +"interface %s.%d already present in the KLD '%s'!\n", + modname, ver, mod->container->filename); + return (EXTERROR(EEXIST, + "module version %jd already loaded", ver)); } } @@ -2376,8 +2402,9 @@ linker_load_dependencies(linker_file_t lf) } error = linker_load_module(NULL, modname, lf, verinfo, NULL); if (error) { - printf("KLD %s: depends on %s - not available or" - " version mismatch\n", lf->filename, modname); + printf( +"KLD %s: depends on %s - not available or version mismatch\n", + lf->filename, modname); break; } } diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h index edc23d7dfbe6..1c3f894e8aff 100644 --- a/sys/sys/exterr_cat.h +++ b/sys/sys/exterr_cat.h @@ -41,6 +41,7 @@ #define EXTERR_CAT_PROCEXIT 16 #define EXTERR_CAT_VMM 17 #define EXTERR_CAT_HWPMC_IBS 18 +#define EXTERR_CAT_LINKER 19 #endif