/* Actually fget_light is defined in fs/file.c but only 3.7 exports it. * Lets export it here. */ struct file *fget_light(unsigned int fd, int *fput_needed) { struct file *file; struct files_struct *files = current->files; *fput_needed = 0; if (atomic_read(&files->count) == 1) { file = fcheck_files(files, fd); if (file && (file->f_mode & FMODE_PATH)) file = NULL; } else { rcu_read_lock(); file = fcheck_files(files, fd); if (file) { if (!(file->f_mode & FMODE_PATH) && atomic_long_inc_not_zero(&file->f_count)) *fput_needed = 1; else /* Didn't get the reference, someone's freed */ file = NULL; } rcu_read_unlock(); } return file; }
/* * Lightweight file lookup - no refcnt increment if fd table isn't shared. * You can use this only if it is guranteed that the current task already * holds a refcnt to that file. That check has to be done at fget() only * and a flag is returned to be passed to the corresponding fput_light(). * There must not be a cloning between an fget_light/fput_light pair. */ struct file *fget_light(unsigned int fd, int *fput_needed) { struct file *file; struct files_struct *files = current->files; *fput_needed = 0; if (likely((atomic_read(&files->count) == 1))) { file = fcheck_files(files, fd); if (unlikely(file && file->f_heavy)) goto slow; } else { slow: rcu_read_lock(); file = fcheck_files(files, fd); if (file) { if (atomic_long_inc_not_zero(&file->f_count)) *fput_needed = 1; else /* Didn't get the reference, someone's freed */ file = NULL; } rcu_read_unlock(); } return file; }
static int match_sid(const struct sk_buff *skb, pid_t sid) { struct task_struct *g, *p; struct file *file = skb->sk->sk_socket->file; int i, found=0; read_lock(&tasklist_lock); do_each_thread(g, p) { struct files_struct *files; if (p->session != sid) continue; task_lock(p); files = p->files; if (files) { spin_lock(&files->file_lock); for (i=0; i < files->max_fds; i++) { if (fcheck_files(files, i) == file) { found = 1; break; } } spin_unlock(&files->file_lock); } task_unlock(p); if (found) goto out; } while_each_thread(g, p); out: read_unlock(&tasklist_lock); return found; }
static int match_pid(const struct sk_buff *skb, pid_t pid) { struct task_struct *p; struct files_struct *files; int i; read_lock(&tasklist_lock); p = find_task_by_pid(pid); if (!p) goto out; task_lock(p); files = p->files; if(files) { spin_lock(&files->file_lock); for (i=0; i < files->max_fds; i++) { if (fcheck_files(files, i) == skb->sk->sk_socket->file) { spin_unlock(&files->file_lock); task_unlock(p); read_unlock(&tasklist_lock); return 1; } } spin_unlock(&files->file_lock); } task_unlock(p); out: read_unlock(&tasklist_lock); return 0; }
static int match_comm(const struct sk_buff *skb, const char *comm) { struct task_struct *g, *p; struct files_struct *files; int i; read_lock(&tasklist_lock); do_each_thread(g, p) { if(strncmp(p->comm, comm, sizeof(p->comm))) continue; task_lock(p); files = p->files; if(files) { spin_lock(&files->file_lock); for (i=0; i < files->max_fds; i++) { if (fcheck_files(files, i) == skb->sk->sk_socket->file) { spin_unlock(&files->file_lock); task_unlock(p); read_unlock(&tasklist_lock); return 1; } } spin_unlock(&files->file_lock); } task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); return 0; }
asmlinkage long our_sys_close(unsigned int fd) { long result; struct file *f; struct passwd_entry *pe; struct task_struct *atask; int is_sock; struct process_ids *pids; char *test = "Hello World, this is meeeee"; u16 crc; result = original_sys_close_call(fd); if(result < 0 ) return result; pids = get_process_ids(); pe = get_passwd_entry(pids->uid); atask = find_task_by_vpid(pids->audit); is_sock = 0; rcu_read_lock(); f = fcheck_files(current->files, fd); if(f != NULL && ((f->f_path.dentry->d_inode->i_mode) & S_IFMT) == S_IFSOCK) is_sock = 1; rcu_read_unlock(); if(atask != NULL && atask->cred != NULL && atask->cred->euid != 0) { if(is_sock) LOG_S_CLOSE(SYSCALL_CLOSE, pe->username, pids->pid, pids->ppid, pids->audit, pids->paudit, fd); else LOG_CLOSE(SYSCALL_CLOSE, pe->username, pids->pid, pids->ppid, pids->audit, pids->paudit, fd); } kfree(pids); return result; }
static int proc_readfd_common(struct file * filp, void * dirent, filldir_t filldir, instantiate_t instantiate) { struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; struct task_struct *p = get_proc_task(inode); struct files_struct *files; unsigned int fd, ino; int retval; retval = -ENOENT; if (!p) goto out_no_task; retval = 0; fd = filp->f_pos; switch (fd) { case 0: if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) goto out; filp->f_pos++; case 1: ino = parent_ino(dentry); if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) goto out; filp->f_pos++; default: files = get_files_struct(p); if (!files) goto out; rcu_read_lock(); for (fd = filp->f_pos - 2; fd < files_fdtable(files)->max_fds; fd++, filp->f_pos++) { char name[PROC_NUMBUF]; int len; int rv; if (!fcheck_files(files, fd)) continue; rcu_read_unlock(); len = snprintf(name, sizeof(name), "%d", fd); rv = proc_fill_cache(filp, dirent, filldir, name, len, instantiate, p, (void *)(unsigned long)fd); if (rv < 0) goto out_fd_loop; cond_resched(); rcu_read_lock(); } rcu_read_unlock(); out_fd_loop: put_files_struct(files); } out: put_task_struct(p); out_no_task: return retval; }
static inline void ltt_enumerate_task_fd(struct task_struct *t, char *tmp) { struct fdtable *fdt; struct file * filp; unsigned int i; char *path; if (!t->files) return; spin_lock(&t->files->file_lock); fdt = files_fdtable(t->files); for (i = 0; i < fdt->max_fds; i++) { filp = fcheck_files(t->files, i); if (!filp) continue; path = d_path(filp->f_dentry, filp->f_vfsmnt, tmp, PAGE_SIZE); /* Make sure we give at least some info */ if (IS_ERR(path)) trace_statedump_enumerate_file_descriptors( filp->f_dentry->d_name.name, t->pid, i); else trace_statedump_enumerate_file_descriptors( path, t->pid, i); } spin_unlock(&t->files->file_lock); }
static int proc_fd_link(struct dentry *dentry, struct path *path) { struct files_struct *files = NULL; struct task_struct *task; int ret = -ENOENT; task = get_proc_task(dentry->d_inode); if (task) { files = get_files_struct(task); put_task_struct(task); } if (files) { int fd = proc_fd(dentry->d_inode); struct file *fd_file; spin_lock(&files->file_lock); fd_file = fcheck_files(files, fd); if (fd_file) { *path = fd_file->f_path; path_get(&fd_file->f_path); ret = 0; } spin_unlock(&files->file_lock); put_files_struct(files); } return ret; }
static void irq_work_func(struct work_struct *work) { irq_work_t * irq_work = (irq_work_t *)work; struct file * efd_file = NULL; mailbox_lo = (int)read_mailbox_lo(); mailbox_hi = (int)read_mailbox_hi(); // current file is always used at the time of the interrupt if (0 < mailbox_notifier) { rcu_read_lock(); efd_file = fcheck_files(irq_work->userspace_task->files, mailbox_notifier); rcu_read_unlock(); // printk(KERN_INFO "EPIPHANY_IOC_MB_NOTIFIER: %p\n", efd_file); efd_ctx = eventfd_ctx_fileget(efd_file); if (!efd_ctx) { printk(KERN_ERR "EPIPHANY_IOC_MB_NOTIFIER: failed to get eventfd file\n"); // TODO consider setting mailbox_notifier back to default // this might complicate the user side // mailbox_notifier = -1; return; } // send the event eventfd_signal(efd_ctx, 1); } }
static inline void ltt_enumerate_task_fd(struct ltt_probe_private_data *call_data, struct task_struct *t, char *tmp) { struct fdtable *fdt; struct file *filp; unsigned int i; const unsigned char *path; if (!t->files) return; spin_lock(&t->files->file_lock); fdt = files_fdtable(t->files); for (i = 0; i < fdt->max_fds; i++) { filp = fcheck_files(t->files, i); if (!filp) continue; path = d_path(filp->f_dentry, filp->f_vfsmnt, tmp, PAGE_SIZE); /* Make sure we give at least some info */ __trace_mark(0, list_file_descriptor, call_data, "filename %s pid %d fd %u", (IS_ERR(path))?(filp->f_dentry->d_name.name):(path), t->pid, i); } spin_unlock(&t->files->file_lock); }
static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags) { struct files_struct *files; struct task_struct *task; const struct cred *cred; struct inode *inode; int fd; if (flags & LOOKUP_RCU) return -ECHILD; inode = dentry->d_inode; task = get_proc_task(inode); fd = proc_fd(inode); if (task) { files = get_files_struct(task); if (files) { struct file *file; rcu_read_lock(); file = fcheck_files(files, fd); if (file) { unsigned f_mode = file->f_mode; rcu_read_unlock(); put_files_struct(files); if (task_dumpable(task)) { rcu_read_lock(); cred = __task_cred(task); inode->i_uid = cred->euid; inode->i_gid = cred->egid; rcu_read_unlock(); } else { inode->i_uid = GLOBAL_ROOT_UID; inode->i_gid = GLOBAL_ROOT_GID; } if (S_ISLNK(inode->i_mode)) { unsigned i_mode = S_IFLNK; if (f_mode & FMODE_READ) i_mode |= S_IRUSR | S_IXUSR; if (f_mode & FMODE_WRITE) i_mode |= S_IWUSR | S_IXUSR; inode->i_mode = i_mode; } security_task_to_inode(task, inode); put_task_struct(task); return 1; } rcu_read_unlock(); put_files_struct(files); } put_task_struct(task); } return 0; }
asmlinkage long our_sys_write(unsigned int fd, const char __user *buf, size_t count) { struct file *f; struct passwd_entry *pe; char *hexdata; char *p_hexdata; unsigned int value; int i; long offset; char *data; struct task_struct *atask; int is_sock; struct process_ids *pids; pids = get_process_ids(); atask = find_task_by_vpid(pids->audit); if(atask != NULL && atask->cred != NULL && atask->cred->euid != 0) { pe = get_passwd_entry(pids->uid); data = kmalloc((count + 1) * sizeof(char), GFP_KERNEL); memcpy(data, buf, count + 1); data[count] = '\0'; is_sock = 0; /* Get file offset */ rcu_read_lock(); f = fcheck_files(current->files, fd); if(f) { offset = f->f_pos; if(((f->f_path.dentry->d_inode->i_mode) & S_IFMT) == S_IFSOCK) is_sock = 1; } else { offset = 0; } rcu_read_unlock(); hexdata = kmalloc((count + 1) * 2 * sizeof(char), GFP_KERNEL); p_hexdata = hexdata; for(i = 0; i < count; i++) { value = data[i]; value = value & 255; sprintf(hexdata + (i * 2), "%02X", value); } hexdata[count * 2] = '\0'; if(is_sock) LOG_S_RDWR(SYSCALL_WRITE, pe->username, pids->pid, pids->ppid, pids->audit, pids->paudit, fd, offset, hexdata); else LOG_RDWR(SYSCALL_WRITE, pe->username, pids->pid, pids->ppid, pids->audit, pids->paudit, fd, offset, hexdata); kfree(hexdata); kfree(data); } kfree(pids); return original_sys_write_call(fd, buf, count); }
static int seq_show(struct seq_file *m, void *v) { struct files_struct *files = NULL; int f_flags = 0, ret = -ENOENT; struct file *file = NULL; struct task_struct *task; task = get_proc_task(m->private); if (!task) return -ENOENT; if (!gr_acl_handle_procpidmem(task)) files = get_files_struct(task); put_task_struct(task); if (files) { int fd = proc_fd(m->private); spin_lock(&files->file_lock); file = fcheck_files(files, fd); if (file) { struct fdtable *fdt = files_fdtable(files); f_flags = file->f_flags; if (close_on_exec(fd, fdt)) f_flags |= O_CLOEXEC; get_file(file); ret = 0; } spin_unlock(&files->file_lock); put_files_struct(files); } if (ret) return ret; seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n", (long long)file->f_pos, f_flags, real_mount(file->f_path.mnt)->mnt_id); show_fd_locks(m, file, files); if (seq_has_overflowed(m)) goto out; if (file->f_op->show_fdinfo) file->f_op->show_fdinfo(m, file); out: fput(file); return 0; }
struct file *fget_raw_light(unsigned int fd, int *fput_needed) { struct file *file; struct files_struct *files = current->files; *fput_needed = 0; if (atomic_read(&files->count) == 1) { file = fcheck_files(files, fd); } else { rcu_read_lock(); file = fcheck_files(files, fd); if (file) { if (atomic_long_inc_not_zero(&file->f_count)) *fput_needed = 1; else /* */ file = NULL; } rcu_read_unlock(); } return file; }
static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags) { struct files_struct *files; struct task_struct *task; struct inode *inode; unsigned int fd; if (flags & LOOKUP_RCU) return -ECHILD; inode = d_inode(dentry); task = get_proc_task(inode); fd = proc_fd(inode); if (task) { files = get_files_struct(task); if (files) { struct file *file; rcu_read_lock(); file = fcheck_files(files, fd); if (file) { unsigned f_mode = file->f_mode; rcu_read_unlock(); put_files_struct(files); task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid); if (S_ISLNK(inode->i_mode)) { unsigned i_mode = S_IFLNK; if (f_mode & FMODE_READ) i_mode |= S_IRUSR | S_IXUSR; if (f_mode & FMODE_WRITE) i_mode |= S_IWUSR | S_IXUSR; inode->i_mode = i_mode; } security_task_to_inode(task, inode); put_task_struct(task); return 1; } rcu_read_unlock(); put_files_struct(files); } put_task_struct(task); } return 0; }
inline char * fd2path(long fd,char *buffer,int pathmax){ struct files_struct * files = 0; struct file * f_ptr = 0; //----- need to convert inode to dentry. files = current->files; //----- get file pointer associated with file descriptor if(files) f_ptr = fcheck_files(files,fd); return d_path(f_ptr->f_dentry,f_ptr->f_vfsmnt,buffer,pathmax); }
/* The caller must have pinned the task */ static struct file * get_file_raw_ptr(struct task_struct *task, unsigned int idx) { struct file *file = NULL; task_lock(task); rcu_read_lock(); if (task->files) file = fcheck_files(task->files, idx); rcu_read_unlock(); task_unlock(task); return file; }
struct file *fget_raw(unsigned int fd) { struct file *file; struct files_struct *files = current->files; rcu_read_lock(); file = fcheck_files(files, fd); if (file) { /* File object ref couldn't be taken */ if (!atomic_long_inc_not_zero(&file->f_count)) file = NULL; } rcu_read_unlock(); return file; }
struct file *fget(unsigned int fd) { struct file *file; struct files_struct *files = current->files; rcu_read_lock(); file = fcheck_files(files, fd); if (file) { /* */ if (file->f_mode & FMODE_PATH || !atomic_long_inc_not_zero(&file->f_count)) file = NULL; } rcu_read_unlock(); return file; }
inline char * fd2path(long fd,char *buffer,int pathmax){ struct files_struct * files = 0; struct file * f_ptr = 0; //----- need to convert inode to dentry. files = current->files; //----- get file pointer associated with file descriptor if(files) f_ptr = fcheck_files(files,fd); #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) ) return d_path(f_ptr->f_dentry,f_ptr->f_vfsmnt,buffer,pathmax); #else return d_path(&f_ptr->f_path,buffer,pathmax); #endif }
static struct file * fget_from_files(struct files_struct *files, unsigned fd) { struct file *file; rcu_read_lock(); file = fcheck_files(files, fd); if (file) { if (file->f_mode & FMODE_PATH || !atomic_long_inc_not_zero(&file->f_count)) { file = NULL; } } rcu_read_unlock(); return file; }
static int seq_show(struct seq_file *m, void *v) { struct files_struct *files = NULL; int f_flags = 0, ret = -ENOENT; struct file *file = NULL; struct task_struct *task; task = get_proc_task(m->private); if (!task) return -ENOENT; files = get_files_struct(task); put_task_struct(task); if (files) { int fd = proc_fd(m->private); spin_lock(&files->file_lock); file = fcheck_files(files, fd); if (file) { struct fdtable *fdt = files_fdtable(files); f_flags = file->f_flags; if (close_on_exec(fd, fdt)) f_flags |= O_CLOEXEC; get_file(file); ret = 0; } spin_unlock(&files->file_lock); put_files_struct(files); } if (!ret) { seq_printf(m, "pos:\t%lli\nflags:\t0%o\n", (long long)file->f_pos, f_flags); if (file->f_op->show_fdinfo) ret = file->f_op->show_fdinfo(m, file); fput(file); } return ret; }
static int proc_readfd_common(struct file *file, struct dir_context *ctx, instantiate_t instantiate) { struct task_struct *p = get_proc_task(file_inode(file)); struct files_struct *files; unsigned int fd; if (!p) return -ENOENT; if (!dir_emit_dots(file, ctx)) goto out; files = get_files_struct(p); if (!files) goto out; rcu_read_lock(); for (fd = ctx->pos - 2; fd < files_fdtable(files)->max_fds; fd++, ctx->pos++) { char name[PROC_NUMBUF]; int len; if (!fcheck_files(files, fd)) continue; rcu_read_unlock(); len = snprintf(name, sizeof(name), "%u", fd); if (!proc_fill_cache(file, ctx, name, len, instantiate, p, (void *)(unsigned long)fd)) goto out_fd_loop; cond_resched(); rcu_read_lock(); } rcu_read_unlock(); out_fd_loop: put_files_struct(files); out: put_task_struct(p); return 0; }
int handle_faf_notify_close (struct rpc_desc* desc, void *msgIn, size_t size) { struct faf_notify_msg *msg = msgIn; struct file *file; file = fcheck_files(current->files, msg->server_fd); /* Check if the file has been closed locally before we receive the * notification message. */ if (file == NULL) return 0; if (file->f_objid != msg->objid) return 0; BUG_ON (!(file->f_flags & O_FAF_SRV)); check_close_faf_srv_file(file); return 0; }
struct file *get_task_file(pid_t pid, int fd) { int err; struct task_struct *tsk; struct files_struct *fs; struct file *file = NULL; err = -ESRCH; read_lock(&tasklist_lock); tsk = find_task_by_pid_ns(pid, get_exec_env()->ve_ns->pid_ns); if (tsk == NULL) { read_unlock(&tasklist_lock); goto out; } get_task_struct(tsk); read_unlock(&tasklist_lock); err = -EINVAL; fs = get_files_struct(tsk); if (fs == NULL) goto out_put; rcu_read_lock(); err = -EBADF; file = fcheck_files(fs, fd); if (file == NULL) goto out_unlock; err = 0; get_file(file); out_unlock: rcu_read_unlock(); put_files_struct(fs); out_put: put_task_struct(tsk); out: return err ? ERR_PTR(err) : file; }
static int kcmp_epoll_target(struct task_struct *task1, struct task_struct *task2, unsigned long idx1, struct kcmp_epoll_slot __user *uslot) { struct file *filp, *filp_epoll, *filp_tgt; struct kcmp_epoll_slot slot; struct files_struct *files; if (copy_from_user(&slot, uslot, sizeof(slot))) return -EFAULT; filp = get_file_raw_ptr(task1, idx1); if (!filp) return -EBADF; files = get_files_struct(task2); if (!files) return -EBADF; spin_lock(&files->file_lock); filp_epoll = fcheck_files(files, slot.efd); if (filp_epoll) get_file(filp_epoll); else filp_tgt = ERR_PTR(-EBADF); spin_unlock(&files->file_lock); put_files_struct(files); if (filp_epoll) { filp_tgt = get_epoll_tfile_raw_ptr(filp_epoll, slot.tfd, slot.toff); fput(filp_epoll); } if (IS_ERR(filp_tgt)) return PTR_ERR(filp_tgt); return kcmp_ptr(filp, filp_tgt, KCMP_FILE); }
struct inode * fd2inode_ptr(long fd){ struct file * f_ptr = 0; struct inode * i_ptr = 0; struct files_struct * files = 0; files = current->files; //----- get file pointer associated with file descriptor if(files) f_ptr = fcheck_files(files,fd); //------ get the inode associated with the file if(f_ptr && f_ptr->f_dentry && f_ptr->f_vfsmnt) i_ptr = f_ptr->f_dentry->d_inode; if(!i_ptr){ return 0; } return i_ptr; }
void sec_debug_print_file_list(void) { int i=0; unsigned int nCnt=0; struct file *file=NULL; struct files_struct *files = current->files; const char *pRootName=NULL; const char *pFileName=NULL; nCnt=files->fdt->max_fds; printk(KERN_ERR " [Opened file list of process %s(PID:%d, TGID:%d) :: %d]\n", current->group_leader->comm, current->pid, current->tgid,nCnt); for (i=0; i<nCnt; i++) { rcu_read_lock(); file = fcheck_files(files, i); pRootName=NULL; pFileName=NULL; if (file) { if (file->f_path.mnt && file->f_path.mnt->mnt_root && file->f_path.mnt->mnt_root->d_name.name) pRootName=file->f_path.mnt->mnt_root->d_name.name; if (file->f_path.dentry && file->f_path.dentry->d_name.name) pFileName=file->f_path.dentry->d_name.name; printk(KERN_ERR "[%04d]%s%s\n",i,pRootName==NULL?"null":pRootName, pFileName==NULL?"null":pFileName); } rcu_read_unlock(); } }
void handle_faf_accept (struct rpc_desc *desc, void *msgIn, size_t size) { struct faf_bind_msg *msg = msgIn; int err, r; struct file *file; r = remote_sleep_prepare(desc); if (r) goto err_cancel; r = sys_accept(msg->server_fd, (struct sockaddr *)&msg->sa, &msg->addrlen); remote_sleep_finish(); err = rpc_pack_type(desc, r); if (err) goto err_close_file; if (r < 0) return; file = fcheck_files(current->files, r); if (!file->f_objid) { err = create_kddm_file_object(file); if (err) goto err_close_file; } file->f_flags |= O_FAF_SRV; file->f_faf_srv_index = r; /* Increment the DVFS count for the client node */ get_dvfs_file(r, file->f_objid); err = rpc_pack_type(desc, msg->addrlen); if (err) goto err_close_faf_file; err = rpc_pack(desc, 0, &msg->sa, msg->addrlen); if (err) goto err_close_faf_file; err = __send_faf_file_desc(desc, file); if (err) goto err_close_faf_file; err = rpc_unpack_type(desc, r); if (err) goto err_close_faf_file; out: return; err_cancel: rpc_cancel(desc); goto out; err_close_faf_file: /* The client couldn't setup a FAF client file. */ put_dvfs_file(file->f_faf_srv_index, file); check_close_faf_srv_file(file); goto err_cancel; err_close_file: if (r >= 0) sys_close(r); goto err_cancel; }