6

I would like to use do_mmap() in a kernel module. According to this question this should be possible.

Here is a minimal non-working example:

hp_km.c:

#include <linux/module.h>
#include <linux/mm.h>

MODULE_LICENSE("GPL");

static int __init hp_km_init(void) {
   do_mmap(0, 0, 0, 0, 0, 0, 0, 0, 0);
   return 0;
}

static void __exit hp_km_exit(void) {
}

module_init(hp_km_init);
module_exit(hp_km_exit);
Makefile:

obj-m += hp_km.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Running make results in WARNING: "do_mmap" [...] undefined!

What do I need to change in hp_km.cor Makefile to make this work?

andreas
  • 143
  • 4
  • 3
    I think you have to export the symbol first. You can do that by adding `EXPORT_SYMBOL(do_mmap);` in the mmap.c file below the definition of the function and then recompile the kernel. You can use any of the functions that have been exported using `EXPORT_SYMBOL`, but note how `do_mmap` has not been exported. – Hadi Brais Mar 23 '19 at 21:02

1 Answers1

4

In addition to rebuild the kernel, you can also use kallsyms_lookup_name to find the address corresponding to the symbol

such as below:

#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kallsyms.h>

MODULE_LICENSE("GPL");

unsigned long (*orig_do_mmap)(struct file *file, unsigned long addr,
                              unsigned long len, unsigned long prot,
                              unsigned long flags, vm_flags_t vm_flags,
                              unsigned long pgoff, unsigned long *populate,
                              struct list_head *uf);

static int __init hp_km_init(void)
{
    orig_do_mmap = (void*)kallsyms_lookup_name("do_mmap");
    if (orig_do_mmap == NULL)
        return -EINVAL;

    orig_do_mmap(0, 0, 0, 0, 0, 0, 0, 0, 0);
    return 0;
}

static void __exit hp_km_exit(void)
{
}

module_init(hp_km_init);
module_exit(hp_km_exit);
ccxxshow
  • 844
  • 6
  • 5