Date: Wed, 3 Jun 2009 15:08:04 +1000 From: Benno Rice <benno@jeamland.net> To: current@freebsd.org Subject: Re: CFR: sanity checking arguments to kldload(8) Message-ID: <F4AAD80A-CDF6-4FD0-82D8-A7FBE0BEB993@jeamland.net> In-Reply-To: <B8E26963-4413-499B-A512-A5ECF997D11A@jeamland.net> References: <B8E26963-4413-499B-A512-A5ECF997D11A@jeamland.net>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On 03/06/2009, at 1:03 PM, Benno Rice wrote:
> The attached patch performs some sanity checking on arguments passed
> to kldload(8). Specifically, if an argument looks like a filename
> but lacks a path (eg, 'xfs.ko' as opposed to 'xfs' or './xfs.ko') it
> checks to see if a file with that name is in the current directory.
> If it is, it checks the current module path to see if a file with
> that name also exists there (possibly in an earlier entry if the
> current directory is in the module path), if so it warns the user
> that that module will be loaded and not the one in the current
> directory. If not, it tells the user how to use a path to load the
> module.
>
> A -q option is added to quieten the output if desired.
I've had some feedback that the instructions on how to load the module
from the current directory
should instead be in the manual page. I've done this and added extra
verbiage to point out the potential source of confusion wherein bare
filenames (eg. foo.ko as opposed to ./foo.ko) will only ever be loaded
from the module path.
Further comments appreciated.
[-- Attachment #2 --]
Index: sbin/kldload/kldload.8
===================================================================
--- sbin/kldload/kldload.8 (revision 193292)
+++ sbin/kldload/kldload.8 (working copy)
@@ -50,10 +50,22 @@
.Nm .
It does not hurt to specify it though.
.Pp
+If a bare filename is requested it will only be loaded if it is found within
+the module path as defined by the sysctl
+.Va kern.module_path .
+To load a module from the current directory it must be specified as a full or
+relative path.
+The
+.Nm
+utility will warn if a module is requested as a bare filename and is present
+in the current directory.
+.Pp
The following option is available:
.Bl -tag -width indent
.It Fl v
Be more verbose.
+.It Fl q
+Silence any extraneous warnings.
.El
.Sh FILES
.Bl -tag -width /boot/kernel -compact
@@ -64,6 +76,26 @@
.El
.Sh EXIT STATUS
.Ex -std
+.Sh EXAMPLES
+To load by module name:
+.Bd -literal -offset indent
+\*[Gt] kldload foo
+.Ed
+.Pp
+To load by file name within the module path:
+.Bd -literal -offset indent
+\*[Gt] kldload foo.ko
+.Ed
+.Pp
+To load by relative path:
+.Bd -literal -offset indent
+\*[Gt] kldload ./foo.ko
+.Ed
+.Pp
+To load by full path:
+.Bd -literal -offset indent
+\*[Gt] kldload /boot/kernel/foo.ko
+.Ed
.Sh AUTOMATICALLY LOADING MODULES
Some modules (pf, ipfw, ipf, etc.) may be automatically loaded at boot
time when the corresponding
Index: sbin/kldload/kldload.c
===================================================================
--- sbin/kldload/kldload.c (revision 193292)
+++ sbin/kldload/kldload.c (working copy)
@@ -30,10 +30,99 @@
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/linker.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#define PATHCTL "kern.module_path"
+
+/*
+ * Check to see if the requested module is specified as a filename with no
+ * path. If so and if a file by the same name exists in the module path,
+ * warn the user that the module in the path will be used in preference.
+ */
+static int
+path_check(const char *kldname, int quiet)
+{
+ int mib[5], found;
+ size_t miblen, pathlen;
+ char kldpath[MAXPATHLEN];
+ char *path, *tmppath, *element;
+ struct stat sb;
+ dev_t dev;
+ ino_t ino;
+
+ if (strchr(kldname, '/') != NULL) {
+ return (0);
+ }
+ if (strstr(kldname, ".ko") == NULL) {
+ return (0);
+ }
+ if (stat(kldname, &sb) != 0) {
+ return (0);
+ }
+
+ found = 0;
+ dev = sb.st_dev;
+ ino = sb.st_ino;
+
+ miblen = sizeof(mib) / sizeof(mib[0]);
+ if (sysctlnametomib(PATHCTL, mib, &miblen) != 0) {
+ err(1, "sysctlnametomib(%s)", PATHCTL);
+ }
+ if (sysctl(mib, miblen, NULL, &pathlen, NULL, 0) == -1) {
+ err(1, "getting path: sysctl(%s) - size only", PATHCTL);
+ }
+ path = malloc(pathlen + 1);
+ if (path == NULL) {
+ err(1, "allocating %lu bytes for the path",
+ (unsigned long)pathlen + 1);
+ }
+ if (sysctl(mib, miblen, path, &pathlen, NULL, 0) == -1) {
+ err(1, "getting path: sysctl(%s)", PATHCTL);
+ }
+ tmppath = path;
+
+ while ((element = strsep(&tmppath, ";")) != NULL) {
+ strlcpy(kldpath, element, MAXPATHLEN);
+ if (kldpath[strlen(kldpath) - 1] != '/') {
+ strlcat(kldpath, "/", MAXPATHLEN);
+ }
+ strlcat(kldpath, kldname, MAXPATHLEN);
+
+ if (stat(kldpath, &sb) == -1) {
+ continue;
+ }
+
+ found = 1;
+
+ if (sb.st_dev != dev || sb.st_ino != ino) {
+ if (!quiet) {
+ warnx("%s will be loaded from %s, not the "
+ "current directory", kldname, element);
+ }
+ break;
+ } else if (sb.st_dev == dev && sb.st_ino == ino) {
+ return (0);
+ }
+ }
+
+ free(path);
+
+ if (!found) {
+ if (!quiet) {
+ warnx("%s is not in the module path", kldname);
+ }
+ return (-1);
+ }
+
+ return (0);
+}
+
static void
usage(void)
{
@@ -48,14 +137,21 @@
int errors;
int fileid;
int verbose;
+ int quiet;
errors = 0;
verbose = 0;
-
- while ((c = getopt(argc, argv, "v")) != -1)
+ quiet = 0;
+
+ while ((c = getopt(argc, argv, "qv")) != -1)
switch (c) {
+ case 'q':
+ quiet = 1;
+ verbose = 0;
+ break;
case 'v':
verbose = 1;
+ quiet = 0;
break;
default:
usage();
@@ -67,13 +163,17 @@
usage();
while (argc-- != 0) {
- fileid = kldload(argv[0]);
- if (fileid < 0) {
- warn("can't load %s", argv[0]);
- errors++;
- } else
- if (verbose)
- printf("Loaded %s, id=%d\n", argv[0], fileid);
+ if (path_check(argv[0], quiet) == 0) {
+ fileid = kldload(argv[0]);
+ if (fileid < 0) {
+ warn("can't load %s", argv[0]);
+ errors++;
+ } else
+ if (verbose)
+ printf("Loaded %s, id=%d\n", argv[0], fileid);
+ } else {
+ errors++;
+ }
argv++;
}
[-- Attachment #3 --]
--
Benno Rice
benno@jeamland.net
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?F4AAD80A-CDF6-4FD0-82D8-A7FBE0BEB993>
