简体   繁体   中英

Opening a file from userspace from a Linux kernel module

I've been following a tutorial for opening files from userspace from a Linux kernel module at http://www.howtoforge.com/reading-files-from-the-linux-kernel-space-module-driver-fedora-14

The code is the following:

#include <linux/module.h>  // Needed by all modules
#include <linux/kernel.h>  // Needed for KERN_INFO
#include <linux/fs.h>      // Needed by filp
#include <asm/uaccess.h>   // Needed by segment descriptors

int init_module(void)
{
    // Create variables
    struct file *f;
    char buf[128];
    mm_segment_t fs;
    int i;
    // Init the buffer with 0
    for(i=0;i<128;i++)
        buf[i] = 0;
    // To see in /var/log/messages that the module is operating
    printk(KERN_INFO "My module is loaded\n");
    // I am using Fedora and for the test I have chosen following file
    // Obviously it is much smaller than the 128 bytes, but hell with it =)
    f = filp_open("/etc/fedora-release", O_RDONLY, 0);
    if(f == NULL)
        printk(KERN_ALERT "filp_open error!!.\n");
    else{
        // Get current segment descriptor
        fs = get_fs();
        // Set segment descriptor associated to kernel space
        set_fs(get_ds());
        // Read the file
        f->f_op->read(f, buf, 128, &f->f_pos);
        // Restore segment descriptor
        set_fs(fs);
        // See what we read from file
        printk(KERN_INFO "buf:%s\n",buf);
    }
    filp_close(f,NULL);
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "My module is unloaded\n");
}

The code is copy-pasted from the link above. On my machine, running Fedora 19 with 3.11.10-200 kernel, it seems that filp_open isn't run, providing the buf variable with null values.

What could be wrong? I am still learning the ropes of Linux kernel module development.

First thing you should do is to check if any errors are returned from filp_open (in fact, checking for NULL is probably an outright mistake when modern kernels are concerned). The proper sequence should be:

f = filp_open("/etc/fedora-release", O_RDONLY, 0);
if (IS_ERR(f)) {
    // inspect the value of PTR_ERR(f), get the necessary clues
    // negative values represent various errors
    // as defined in asm-generic/errno-base.h
}

Only then you can move on to diagnosing the read.

977 struct file *filp_open(const char *filename, int flags, umode_t mode)
978 {
979         struct filename *name = getname_kernel(filename);
980         struct file *file = ERR_CAST(name);
981         
982         if (!IS_ERR(name)) {
983                 file = file_open_name(name, flags, mode);
984                 putname(name);
985         }
986         return file;
987 }

Probably the error is in how you put the parameters, the flags parameter is in mode parameter position and vice versa, mode in falgs position.

source: http://lxr.free-electrons.com/source/fs/open.c#L977

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM