diff mbox series

[kmod,3/3] Add modprobe -I/--ignore-cmdline

Message ID c302d0b1da1410dd496444f267fee6d5373dbb71.1701791668.git.nabijaczleweli@nabijaczleweli.xyz (mailing list archive)
State New, archived
Headers show
Series [kmod,1/3] Add kmod_new_flags() variant of kmod_new(), with abiver 32 | expand

Commit Message

наб Dec. 5, 2023, 3:55 p.m. UTC
Previously, if you'd misconfigured the cmdline your system would be
completely poisoned.

In this real scenario, ixgbe.allow_supported_sfp=1,1,1,1 was set.
This yielded
  [ 3852.901900] ixgbe: `1,1,1,1' invalid for parameter `allow_unsupported_sfp'
  [ 3852.904595] ixgbe: unknown parameter 'allow_supported_sfp' ignored
and
  # modprobe -r ixgbe
  # modprobe ixgbe allow_supported_sfp=1
since, indeed,
  # modprobe -nv ixgbe
  insmod /lib/modules/5.16.0-1-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko allow_unsupported_sfp=1,1,1,1
  # modprobe -nv ixgbe allow_supported_sfp=1
  insmod /lib/modules/5.16.0-1-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko allow_unsupported_sfp=1,1,1,1 allow_supported_sfp=1
this leaves you with a tens-of-minutes-long reboot
(or with an explicit insmod, which no-one came up with at the time,
 and which requires manual dependency-chasing).

With -I, the module can be correctly loaded since the cmdline-derived
parameter no longer stops the module loading:
  # modprobe -nvI ixgbe allow_supported_sfp=1
  insmod /lib/modules/5.16.0-1-amd64/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko allow_supported_sfp=1
  # modprobe -I ixgbe allow_supported_sfp=1
  [ 4497.032342] ixgbe: Intel(R) 10 Gigabit PCI Express Network Driver
  [ 4497.034624] ixgbe: Copyright (c) 1999-2016 Intel Corporation.

This in many ways mirrors -C /dev/null and -i.
You could, I s'pose, unshare -m and mount --bind /dev/null /proc/cmdline.
But you could say the same of -C in general.

Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
 man/modprobe.xml | 16 ++++++++++++++++
 tools/modprobe.c |  9 +++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/man/modprobe.xml b/man/modprobe.xml
index 91f9e27..ab9dbb0 100644
--- a/man/modprobe.xml
+++ b/man/modprobe.xml
@@ -47,6 +47,7 @@ 
       <arg><option>-C <replaceable>config-file</replaceable></option></arg>
       <arg><option>-n</option></arg>
       <arg><option>-i</option></arg>
+      <arg><option>-I</option></arg>
       <arg><option>-q</option></arg>
       <arg><option>-b</option></arg>
       <arg><replaceable>modulename</replaceable></arg>
@@ -58,6 +59,7 @@ 
       <arg><option>-v</option></arg>
       <arg><option>-n</option></arg>
       <arg><option>-i</option></arg>
+      <arg><option>-I</option></arg>
       <arg rep='repeat'><option><replaceable>modulename</replaceable></option></arg>
     </cmdsynopsis>
     <cmdsynopsis>
@@ -318,6 +320,20 @@ 
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <option>-I</option>
+        </term>
+        <term>
+          <option>--ignore-cmdline</option>
+        </term>
+        <listitem>
+          <para>
+            This option causes <command>modprobe</command> to ignore
+            any configuration specified via the kernel command line.
+          </para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term>
           <option>-n</option>
diff --git a/tools/modprobe.c b/tools/modprobe.c
index e891028..f0e406b 100644
--- a/tools/modprobe.c
+++ b/tools/modprobe.c
@@ -59,7 +59,7 @@  static int remove_holders = 0;
 static unsigned long long wait_msec = 0;
 static int quiet_inuse = 0;
 
-static const char cmdopts_s[] = "arw:RibfDcnC:d:S:sqvVh";
+static const char cmdopts_s[] = "arw:RiIbfDcnC:d:S:sqvVh";
 static const struct option cmdopts[] = {
 	{"all", no_argument, 0, 'a'},
 
@@ -72,6 +72,7 @@  static const struct option cmdopts[] = {
 	{"first-time", no_argument, 0, 3},
 	{"ignore-install", no_argument, 0, 'i'},
 	{"ignore-remove", no_argument, 0, 'i'},
+	{"ignore-cmdline", no_argument, 0, 'I'},
 	{"use-blacklist", no_argument, 0, 'b'},
 	{"force", no_argument, 0, 'f'},
 	{"force-modversion", no_argument, 0, 2},
@@ -835,6 +836,7 @@  static int do_modprobe(int argc, char **orig_argv)
 	const char *dirname = NULL;
 	const char *root = NULL;
 	const char *kversion = NULL;
+	int ignore_cmdline = 0;
 	int use_all = 0;
 	int do_remove = 0;
 	int do_show_config = 0;
@@ -881,6 +883,9 @@  static int do_modprobe(int argc, char **orig_argv)
 		case 'i':
 			ignore_commands = 1;
 			break;
+		case 'I':
+			ignore_cmdline = 1;
+			break;
 		case 'b':
 			use_blacklist = 1;
 			break;
@@ -1004,7 +1009,7 @@  static int do_modprobe(int argc, char **orig_argv)
 		dirname = dirname_buf;
 	}
 
-	ctx = kmod_new(dirname, config_paths);
+	ctx = kmod_new_flags(dirname, config_paths, ignore_cmdline ? KMOD_NEW_IGNORE_CMDLINE : 0);
 	if (!ctx) {
 		ERR("kmod_new() failed!\n");
 		err = -1;