Junaid
Junaid

Reputation: 1678

How to get userID when writing Linux kernel module

Here is my function in my kernel module which I insert using insmod command after make at later stages. I am working on goldfish (2.6.29)

asmlinkage long our_sys_read(unsigned int fd, char  *buf, size_t count)
{
      printk("------->> our_sys_read getuid() ---------- %d\n", getuid());

      return original_call_read(fd,buf,count);
}

I want to trap system calls and find out which user made these system calls. But when I run 'make', it throws me following error.

/home/mohsin/LKM/trapcall.c:245: error: implicit declaration of function 'getuid'

Any suggestion would be appreciated.

Upvotes: 5

Views: 18109

Answers (4)

Daniel
Daniel

Reputation: 3513

Getting the UID without using the getuid syscall hook:

#include "linux/cred.h"

static inline uid_t get_uid(void) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
#include "linux/uidgid.h"
    // current_uid() returns struct in newer kernels
    return __kuid_val(current_uid());
#else
    return 0 == current_uid();
#endif
}

You should also look through linux/uidgid.h for useful macros that define ROOT uid/gid as well as inline comparison functions to avoid directly calling __kuid_val().

For example, a common use would be to check if the user is root:

static inline bool is_root_uid(void) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
#include "linux/uidgid.h"
    // current_uid() returns struct in newer kernels
    return uid_eq(current_uid(), GLOBAL_ROOT_UID);
#else
    return 0 == current_uid();
#endif
}

Upvotes: 1

Junaid
Junaid

Reputation: 1678

After spending two days, I finally figured out how to get uid of the process who made a system call. I will give all the suggestions I found on different links so that if my solution does not work, one of the others may work.

1) As told me Mats,

#include <include/linux/cred.h>

 static int getuid()
 {
     return current_uid();
 }

You call this function to get uid but it gave me negative numbers like -943124788 etc.

2)

uid_t credd_uid ;
const struct cred *cred = current_cred();
credd_uid = current->cred->uid; 

Same output like large negative numbers.

3)

uid_t struct_uid;
struct user_struct *u = current_user();

struct_uid = get_uid(u);

4) Worked Solution

It's given here actually.

i) Declare function prototype on the top like

asmlinkage int (*getuid_call)();

ii) Add following line to init_module() function

/* Get the system call for getuid */

  getuid_call = sys_call_table[__NR_getuid];

iii) Call the function in your trapped system call functions to get uid like

uid_t uid = getuid_call();

Upvotes: 6

dan3
dan3

Reputation: 2559

You need to call current_uid(), defined in linux/cred.h (starting with 2.6, used to be current->uid before). See the kernel doc about credentials

current is a macro, BTW.

Upvotes: 5

Mats Petersson
Mats Petersson

Reputation: 129374

You could perhaps use this:

 #include <include/linux/cred.h>

 static int getuid()
 {
     return current_uid();
 }

cred stands for "credentials", and this macro returns the user-id of the currently active credentials. Bear in mind however that the "current user id" can mean multiple things in Linux.

[dan3 obviously didn't have to dig through quite as much code as I did to find this - or he started before me!]

Upvotes: 6

Related Questions