long my_sys_open(const char __user *filename, int flags, int mode) { long ret; ret = orig_sys_open(filename, flags, mode); printk(KERN_DEBUG "file %s has been opened with mode %d\n", filename, mode); return ret; }
int translucent_create_whiteout(char *file) { int (*orig_sys_close)(int)=sys_call_table[__NR_close]; int (*orig_sys_fchmod)(int,mode_t)=sys_call_table[__NR_fchmod]; int result; BEGIN_KMEM result=orig_sys_open(file, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC, 0); // printk("translucent whiteout %s result %i\n", file, result); END_KMEM; if(result<0) return result; orig_sys_fchmod(result, 01001); orig_sys_close(result); return 0; }
/** create a copy of a regular file in overlay @param nd specifies underlay - source to copy @param nnew specifies new entry - destination @return 0 on success, -ECODE otherwise */ int translucent_copy(struct nameidata *nd, struct nameidata *nnew, int lookup_flags) { char *p, *buf, *pathbuf; ssize_t (*sys_write)(int fd, const void *buf, size_t count)=sys_call_table[__NR_write]; ssize_t (*sys_read)(int fd, void *buf, size_t count)=sys_call_table[__NR_read]; int (*sys_close)(int fd)=sys_call_table[__NR_close]; int result,inphandle,outphandle; int i_Bufsize=4096; umode_t mode=nd->dentry->d_inode->i_mode; struct utimbuf timebuf={ actime:nd->dentry->d_inode->i_atime, modtime:nd->dentry->d_inode->i_mtime }; // exclude device/pipe/socket/dir and proc entries from COW if(is_special(nd)) return -ENODEV; mode &= S_IRWXUGO; buf=malloc(i_Bufsize); pathbuf=malloc(REDIR_BUFSIZE+1); p = d_path(nd->dentry, nd->mnt, pathbuf, REDIR_BUFSIZE); // printk(KERN_DEBUG SYSLOGID ": copy-on-write %s %o\n",p,mode); BEGIN_KMEM result=orig_sys_open(p,O_RDONLY,0666); END_KMEM if(result<0) goto out_free; inphandle=result; p=d_path(nnew->dentry, nnew->mnt, pathbuf, REDIR_BUFSIZE); BEGIN_KMEM result=orig_sys_open(p,O_WRONLY|O_CREAT,mode); END_KMEM if(result<0) goto out_close; outphandle=result; if(!(lookup_flags&LOOKUP_TRUNCATE)) { BEGIN_KMEM while((result=sys_read(inphandle,buf,i_Bufsize))>0&&sys_write(outphandle,buf,result)>0); END_KMEM } else result=0;
/* * Intercept open() */ asmlinkage long my_sys_open(const char __user *filename, int flags, int mode) { long errno; int ret = 0; int temp[4] = _NULL_BIT_; ret = orig_sys_access(filename, _MY_MODE_); errno = orig_sys_open(filename, flags, mode); if (errno < 0) { goto OUT; } if (mode || O_EXCL) { set_bit(_FILE_CREATE_BIT_, (void *)&temp); process_file_name(filename, temp); goto OUT; } if (mode || O_CREAT) { if (ret < 0) { set_bit(_FILE_CREATE_BIT_, (void *)&temp); process_file_name(filename, temp); goto OUT; } } if (mode || O_TRUNC) { set_bit(_FILE_CREATE_BIT_, (void *)&temp); process_file_name(filename, temp); goto OUT; } OUT: return errno; }
/* * sys_open hook. Also registers system call info to history. */ int my_sys_open(const char __user *filename, int flags, umode_t mode) { struct timeval time; unsigned long local_time; struct rtc_time tm; struct history_node *line_to_add = NULL, *last_history_node = NULL; char *pathname = NULL,*p = NULL; struct mm_struct *mm = current->mm; mutex_lock_killable(&file_enabled_mutex); // Check if the module is enabled if(is_file_monitor_enabled) { // Get full path to the current process executable if (mm) { down_read(&mm->mmap_sem); if (mm->exe_file) { pathname = kmalloc(PATH_MAX, GFP_ATOMIC); if(unlikely(!pathname)) { printk(KERN_ERR "Not enough memory for pathname! \n"); mutex_unlock(&file_enabled_mutex); return orig_sys_open(filename, flags, mode); } p = d_path(&mm->exe_file->f_path, pathname, PATH_MAX); } up_read(&mm->mmap_sem); } // Get current time do_gettimeofday(&time); local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60)); rtc_time_to_tm(local_time, &tm); // Write to dmesg printk("%s (pid %i) is opening %s\n", p, current->pid, filename); // Save to history line_to_add = (struct history_node *)kmalloc(sizeof(struct history_node), GFP_KERNEL); if(unlikely(!line_to_add)) { printk(KERN_ERR "Not enough memory for history_node!\n"); mutex_unlock(&file_enabled_mutex); return orig_sys_open(filename, flags, mode); } snprintf(line_to_add->msg, MAX_HISTORY_LINE, "%02d/%02d/%04d %02d:%02d:%02d, %s (pid %i) is opening %s\n", tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec, p, current->pid, filename); line_to_add->time_in_sec = (u32)time.tv_sec; mutex_lock_killable(&file_history_mutex); list_add(&(line_to_add->node), &(file_mon_history.node)); curr_num_of_history_lines++; // If more then 10 lines delete the oldest one if(curr_num_of_history_lines > MAX_HISTORY) { last_history_node = list_last_entry(&(file_mon_history.node), struct history_node, node); list_del(&(last_history_node->node)); kfree(last_history_node); curr_num_of_history_lines--; } mutex_unlock(&file_history_mutex); kfree(pathname); }