3

Linux Kernel 5.0.0-37

I'm writing a function to manage permissions to be provided as a function pointer to the struct inode_operations. Here is a simplified stub implementation:

#include <linux/cred.h>

int pfsw_permission(struct inode *ino, int op){
    if(uid_eq(INIT_USER->uid, get_current_user()->uid)){
        printk(KERN_INFO "Current user is root\n");
    } else {
        printk(KERN_INFO "Current user is not root\n");
    }
    if(op & (MAY_READ | MAY_WRITE)){
        return 0;
    }

    return -EACCES;
}

when compiling a kernel module containing this function and trying to load it dmesg shows the following error:

Unknown symbol root_user (err -2)

This I think is due to INIT_USER macro coming from include/linux/sched/user.h which is defined as

extern struct user_struct root_user;
#define INIT_USER (&root_user)

QUESTION: Why is the symbol root_user declared, but not defined? How to use INIT_USER correctly?

St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • 3
    This is certainly not the right way to accomplish whatever your goal is. Do some thinking about what existing piece of standard functionality would have a similar need, and then look up how that was implemented. – Chris Stratton Dec 25 '19 at 05:12

1 Answers1

2

root_user does not seem to be exported using EXPORT_SYMBOL by the linux kernel; therefore you cannot use it from a module.

Looking at its definition we can see that the uid value is set to GLOBAL_ROOT_UID. This is a macro defined in include/linux/uidgid.h and is basically just a type cast of 0 to kuid_t so you can use just that macro if all you need is the UID.

So ...

Why is the symbol root_user declared, but not defined?

The symbol is defined. It's not exported though so you cannot use it from a module.

How to use INIT_USER correctly?

"Not". You cannot use it.

Daniel Jour
  • 15,896
  • 2
  • 36
  • 63