2

This answer shows us how the current working directory in kernel code. I tried to implement this in my module but without success, I really need someone to share with me a full program with the answer above. Because I really don't know how to use the answer above and how implement it.

I tried the following:

which struct do I need to use in the get_fs_pwd function, and what is the pwd argument? The answer didn't provide an example of how to really get the cwd.

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs_struct.h>

MODULE_LICENSE("GPL");

static int hello_init(void)
{
    printk(KERN_ALERT "Hello, World\n");
    get_fs_pwd(); // which struct do I need to use, and what is the pwd argument?
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_ALERT "Goodbye, cruel world.\n");
}

module_init(hello_init);
module_exit(hello_exit);
static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd)
{
    spin_lock(&fs->lock);
    *pwd = fs->pwd;
    path_get(pwd);
    spin_unlock(&fs->lock);
}
Dudu Faruk
  • 43
  • 1
  • 5
  • 7
    What would be the meaning of the "current directory" in the context of kernel module? – Eugene Sh. Sep 08 '20 at 14:55
  • @EugeneSh. As it sounds, the current directory of my current user. Just like the `pwd` command. – Dudu Faruk Sep 08 '20 at 15:06
  • @DuduFaruk Can't your user have multiple terminals opened with different current directories? Or you mean the directory from which your kernel module was `insmod`ed? – red0ct Sep 08 '20 at 15:08
  • Current directory is process-specific. The linked answer is for getting the pwd of the calling process. In _init I suppose it would be the current directory of the insmod process. Dependng on the implementation of insmod, it may be under /lib/modules/... at that point. – stark Sep 08 '20 at 15:15
  • 1
    @red0ct @ stark I want to get the current working directory of the current process running, from which the module was insert into the kernel. – Dudu Faruk Sep 08 '20 at 16:51

1 Answers1

1

The following kernel code is an example of get_fs_pwd function. Using dmesg command, you will see the directory where the kernel module was insmoded, actually the current working directory of insmod process.

As defined in get_fs_pwd, you need to initialize a variable of struct path, which stores the result extracted from struct fs_struct. Here is current->fs, the filesystem information of current process.

As defined in d_path, you need to kmalloc a string buffer, by which the actual path name can be extracted from struct path. Don't forget to kfree the buffer after use.

#include <linux/dcache.h>
#include <linux/fs_struct.h>
#include <linux/init.h>
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>

MODULE_LICENSE("GPL");

static int __init hello_init(void) {
    struct path pwd;
    char *cwd = NULL;
    char *buf = NULL;

    printk(KERN_ALERT "Hello World\n");
    get_fs_pwd(current->fs, &pwd);
    buf = kmalloc(PATH_MAX, GFP_ATOMIC | __GFP_NOWARN | __GFP_ZERO);
    if (buf) {
        cwd = d_path(&pwd, buf, PATH_MAX);
        printk(KERN_ALERT "The current working directory: %s\n", cwd);
        kfree(buf);
    }

    return 0;
}

static void __exit hello_exit(void) {
    printk(KERN_ALERT "Goodbye World\n");
}

module_init(hello_init);
module_exit(hello_exit);

If the kernel code is saved as hello.c, the following Makefile is for your reference.

obj-m += hello.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
Cipher Saw
  • 171
  • 1
  • 2
  • 7