리눅스 커널 인자로 문자열을 넘길때 공백을 넣는 방법.

Posted by 미스란디르 Mon, 19 Feb 2007 15:25:00 GMT

어떤 리눅스 커널 모듈을 만들었다고 치고.


insmod xxx.ko test=hello world

저러면 원하는대로 test에 hello world라는 값을 넣을 수 없다.

요건 어찌하면 좋을까?

쉘에서 분리하지 않게 test=”hello world” 해도 안된다.

insmod.c를 살펴보면,

    for (i = 2; i < argc; i++) {
        options = realloc(options,
                  strlen(options) + 1 + strlen(argv[i]) + 1); 
        strcat(options, argv[i]);
        strcat(options, " ");
    }   
.
.
.
    ret = init_module(file, len, options);
요게 전부다.

따로 strtok를 하지도 않고 그냥 붙여서 init_module 해버린다.

그런데 저 init_module을 사실은 시스템콜이다. 본체를 찾아보니 kernel/module.c 에 @sys_init_module@이 있다.

요녀석은 다시

mod = load_module(umod, len, uargs);

로 넘긴다.

이녀석을 찾아보면,

    args = strndup_user(uargs, ~0UL >> 1);
.
.
.

    mod->args = args;
    if (obsparmindex)
        printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
               mod->name);

    /* Size of section 0 is 0, so this works well if no params */
    err = parse_args(mod->name, mod->args,
             (struct kernel_param *)
             sechdrs[setupindex].sh_addr,
             sechdrs[setupindex].sh_size
             / sizeof(struct kernel_param),
             NULL);

뭐 이런걸 찾을 수 있다.

parse_args를 찾아 kernel/params.c로 뛰어보면,


        args = next_arg(args, &param, &val);
        irq_was_disabled = irqs_disabled();
        ret = parse_one(param, val, params, num, unknown);

슬슬 목표에 가까워지는 기분이다.

우선 next_arg



static char *next_arg(char *args, char **param, char **val)
{
    unsigned int i, equals = 0;
    int in_quote = 0, quoted = 0;
    char *next;

    if (*args == '"') {
        args++;
        in_quote = 1;
        quoted = 1;
    }

“로 시작하면 인용문자열이라고 인식하는거다.


    for (i = 0; args[i]; i++) {
        if (args[i] == ' ' && !in_quote)
            break;
        if (equals == 0) {
            if (args[i] == '=')
                equals = i;
        }
        if (args[i] == '"')
            in_quote = !in_quote;
    }

이제 공백이 나왔는데 인용문자열이 아니면 끝내는거다. 바로 요거다. 공백을 넣으려면 “로 싸야한다. 그 다음은 = 이 나왔을때 등호의 위치를 기억해두는거다. 그리고 그 다음은 quote상태를 토글하는거고.

그 밑에는 등호의 위치를 이용해서 param과 val를 나누고, val에서 “를 빼는 따위의 짓을 한다.

이제 대충 결론이 났다. test에 Hello world를 넣으려면,


insmod xxx.ko 'test="Hello world"'
라고 해주면 되겠다.

Posted in  | Tags , , ,  | 1 comment | no trackbacks