9

What is the right way of calling kernel functions in a C file from a kernel module in Linux?

I want to call exit_task_namespaces in linux/nsproxy.c from my first ever kernel module

I am doing this:

#include <linux/nsproxy.h>
…

static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset)
{
    struct task_struct *task = current;
    …
    exit_task_namespaces(task);
    …
}

when I try to make I get the following error:

ERROR: "exit_task_namespaces" [/home/.../lkm_example.ko] undefined!
make[2]: *** [scripts/Makefile.modpost:94: __modpost] Error 1
make[1]: *** [Makefile:1673: modules] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-73-generic'
make: *** [Makefile:3: all] Error 2

I can see that in the file /usr/src/linux-headers-5.4.0-73-generic/include/linux/nsproxy.h the method exists.

This is my Makefile:

obj-m += lkm_example.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
5
  • 2
    As an aside, you should really be using $(MAKE) rather than make in your sub-make invocation. – Toby Speight Jun 17 at 6:02
  • 2
    How the MAKE Variable Works. For example: - $(MAKE) implicitly has + at the beginning, so it will run make -n when invoked by make -n, so you can see all the commands that will run. – Toby Speight Jun 17 at 16:25
  • Thanks @TobySpeight... I (think) understand now - thanks for sharing! – Carlos Garcia Jun 17 at 18:51
  • 1
    exit_task_namespaces being called from a module is massively wrong; there is no way this would ever be exported for module use. It's a subroutine of the do_exit logic for terminating a process. Calling these functions randomly on a running task could leave it in a bad state with something depending on the cleaned-up resources to still be there. It's very curious how you arrived at the idea of targeting this specific function from a module. – Kaz Jun 18 at 1:56
  • Hi @Kaz! Very good point :) maybe I should have added the reason into the question. I am simply trying to learn the kernel code - this module will never be used for any real thing. I am a still trying to figure out what is the best way to dig into the code, so I am trying to create a module, add some traces and start calling here and there to check results. For example, I changed the task->nsproxy from the module and it did not do what i expected :( – Carlos Garcia Jun 18 at 8:19
21

Modules can only access exported symbols, and exit_task_namespaces isn’t exported — so even though it is visible in the header files, it can’t be used in a module.

Exported symbols can be accessed as you’d expect, there’s nothing special to do.

5
  • Thank you @StephenKitt! A new thing to learn :) – Carlos Garcia Jun 16 at 20:59
  • 1
    Note: you can use kallsyms_get_name() if you really HAVE to, but it's considered a bad practice. – kiler129 Jun 17 at 4:23
  • 8
    @kiler129 I’m guessing you’re referring to kallsyms_lookup_name — but that is no longer exported to modules, so it’s not only considered bad practice, it’s become rather difficult, although there are still workarounds. – Stephen Kitt Jun 17 at 5:29
  • 2
    @StephenKitt: And last time I checked you can build a stripped kernel that doesn't even have non-exported symbols in the symbol table. – Joshua Jun 17 at 14:52
  • @Joshua you can indeed! – Stephen Kitt Jun 17 at 15:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.