struct nameidata-Linux Kernel Module

43 Views Asked by At

I'm working on a Linux kernel module and trying to apply a kprobe on path_openat function. After that, I need to work with the nameidata structure, which is the first of three parameters of that function.

I've included namei.h, but it doesn't recognize the structure and return invalid use of undefined type struct nameidata.

Is it inaccessible to programmers? By the way, I have the same problem with struct open_flags.

I've tried to manually import the structure with a custom header but it isn't a good solution in particular for portability.

This kprobe is a parth of bigger project: I'm trying to realize a custom reference monitor that check operation like open, unlink, rename etc on file and directory. This is path_openat pre handler:

static int openat_pre_handler(struct kretprobe_instance *p, struct pt_regs *the_regs){
    // path openat pre handler

    struct nameidata * nd;
    struct open_flags * op_flags;
    struct inode * inode;
    struct filename * pathname_struct;
    const char *pathname;
    int flags;

    // Check if the module is OFF or REC-OFF, in that case doesn't need to execute the post handler
    if(monitor->state == 0 || monitor->state == 1)
        goto end;


    atomic_inc((atomic_t*)&open_audit_counter);

    // x86-64 syscall calling convention: %rdi, %rsi, %rdx, %r10, %r8 and %r9.
   
    /*path_openat(struct nameidata *nd, const struct open_flags *op, unsigned flags)*/

    // nameidata is the first parameter, it contains the inode and filename.
    nd = (struct nameidata *) the_regs->di; 
    inode = nd->inode;
    pathname_struct = nd->name;
    pathname = pathname_struct->name;

    // open_flag is the second parameter
    op_flags = (struct open_flags *) the_regs->si; 
    flags = op_flags->open_flag;
    
    // Check if the file is opened WRITE-ONLY or READ-WRITE
    if (flags & O_WRONLY || flags & O_RDWR){
        
        // Check if file is protected
        if (inode_in_protected_paths(inode->i_ino)){
            // ADD WRITE-REPORT ON LOG FILE
            printk("%s: Access on %s blocked correctly \n", MODNAME,pathname);
            //print_flag(flags);
            //The kretprobe post handler should be executed: the access must be blocked
            return 0;
        }

    } 

end: 
    // Doesn't execute the post handler, the access is legit
    return 1;
}

I may have included more than necessary:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/fs.h>
#include <linux/printk.h>    
#include <linux/spinlock.h>  
#include <linux/file.h>
#include <linux/version.h>
#include <linux/path.h> 
#include <linux/slab.h>
#include <linux/fdtable.h>
#include <linux/fs_struct.h>
#include <linux/namei.h>
#include <linux/dcache.h>
0

There are 0 best solutions below