Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a string parameter with space character to kernel module

module name: params.ko


#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/stat.h>
MODULE_LICENSE("Dual BSD/GPL");

static char *mystring = "this is my char string";
module_param(mystring, charp, S_IRUGO | S_IWUSR); 
MODULE_PARM_DESC(mystring, "A char string");

static int __init params_init(void)
{
  printk("Driver is loaded\n");
  printk("   My char string(mystring): %s\n", mystring);
  return 0;
}

static void __exit params_exit(void) { printk("Driver is unloaded\n"); }

module_init(params_init); module_exit(params_exit);

When I use the default setting, I can see the "this is my char string" when the driver is loaded.

However, if I use command line to pass the string with space, it will show up the following error:

Ex1: # insmod ./params.ko mystring="Hello World"

insmod: error inserting './params.ko': -1 Unknown symbol in module

The dmesg shows up the following information:

params: Unknown parameter 'World'

Ex2: # insmod ./params.ko mystring="HelloWorld"

If I use "HelloWorld" without space, there is no problem to show the string.

I also tried to use \ or ' ' to see if I can escape that space to ignore the space but in vain.

Would like to consult anyone who knows how to pass a string containing the space to the kernel module?

Thank you and appreciate your help.

like image 572
rickhau Avatar asked Aug 26 '14 14:08

rickhau


1 Answers

When you run insmod ./params.ko mystring="Hello World" your quotes are eaten by the shell and the insmod binary has the string mystring=Hello World as the parameter. It passes it to the kernel as is, and then it all goes down to the kernel parse_args function (in kernel/params.c), which, in turn, calls next_arg to split the next parameter into name and value.

It definitely can handle spaces, as we see the following comment in the code:

/* You can use " around spaces, but can't escape ". */
/* Hyphens and underscores equivalent in parameter names. */

and the following conditional statement:

static char *next_arg(char *args, char **param, char **val)
{
    ...
    for (i = 0; args[i]; i++) {
        if (isspace(args[i]) && !in_quote)
            break;
    ...
}

So the idea is that you need to pass the quotes to the kernel, not to the shell. Don't have a linux box to check the kernel module insertion right now, but I guess the following command will work:

# insmod ./params.ko mystring='"Hello World"'

Here the shell will consume the single quotes, and the parameter for insmod binary will be mystring="Hello World" so these quotes will be passed to kernel as is, which will make it possible to parse the value as you expect. Try that, should work.

like image 195
afenster Avatar answered Oct 07 '22 23:10

afenster