My goal is to modify a process's open file descriptor's access permission. For eg, there is a process whose PID is known, which has 2 file descriptors open apart from the standard 3. One was opened with read only permission and other was opened with write only permission. I want to modify the file descriptors permission from read only to read and write. After which, the file descriptor can be used to write the object it was created with.
I have written a kernel module that gives me access to the file descriptor of the process identified by its PID. I searched the header and forums to understand how the linux data structure works for handling the file descriptor but I am still confused. What I found out is, every process has its own task_struct, which contains a member for all open files under, which contains an array of open file descriptor. I do not know how it links from here on with the inode.
I found out that there is member of struct file, called as f_mode that gives us the permissions but I cannot find a method to call it. When I access it directly, it gives me an unsigned int but I don't know what value maps to what? Also, I am not sure if this is the data member which stores the access permissions. If I modify this would it change the access permissions for file descriptor?
The code is given below:
static int __init mainInit(void){
int pid=13433;
struct task_struct * task;
struct files_struct * files;
struct fdtable * filestable;
struct path files_path;
//Get Task structure from PID
task = pid_task(find_vpid(pid), PIDTYPE_PID );
//Get open FIles from the task tstructure
files = task->files;
filestable=files_fdtable(files);
int i=0;
char *cwd;
char *buf = (char *)kmalloc(GFP_KERNEL,100*sizeof(char));
while(filestable->fd[i] != NULL){
files_path = filestable->fd[i]->f_path;
cwd=d_path(&files_path,buf, 100*sizeof(char));
printk(KERN_INFO "Open FD with %d with name %s with access %x\n", i, cwd,filestable->fd[i]->f_mode);
//printk(KERN_INFO "FMode read:%x Fmodewrite:%x\n",FMODE_READ,FMODE_WRITE);
//Check access mode
if(filestable->fd[i]->f_mode==FMODE_READ){
printk(KERN_INFO "File has access FMODE_READ\n");
}else if(filestable->fd[i]->f_mode==FMODE_WRITE){
printk(KERN_INFO "File has access FMODE_WRTIE\n");
}
i++;
}
return 0;
}
static void __exit mainExit(void){
printk(KERN_INFO "Goodbye Kernel!. Returning to normal useless world!\n");
}
module_init(mainInit);
module_exit(mainExit);