opt
/
kaspersky
/
kav4fs
/
src
/
kernel
/
module.linux
➕ New
📤 Upload
✎ Editing:
files.c
← Back
/* * This source file is a part of a Kaspersky Antivirus Monitor. * Copyright (C) Kaspersky Lab, 1997-2010 * See License.txt for details * */ #include "module.h" #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 24)) char* d_path_wrap(struct dentry* dentry, struct vfsmount* vfsmnt, char* buf, int buflen) { struct path f_path = {.dentry = dentry, .mnt = vfsmnt}; return d_path(&f_path, buf, buflen); } static inline struct vfsmount* get_cur_fs_rootmnt(void) { return current->fs->root.mnt; } static inline struct dentry* get_cur_fs_root(void) { return current->fs->root.dentry; } #else char* d_path_wrap(struct dentry* dentry, struct vfsmount* vfsmnt, char* buf, int buflen) { return d_path(dentry, vfsmnt, buf, buflen); } static inline struct vfsmount* get_cur_fs_rootmnt(void) { return current->fs->rootmnt; } static inline struct dentry* get_cur_fs_root(void) { return current->fs->root; } #endif static char* get_fname_part(char* buf, char* bufend) { char *part, *res; int len; for (part = bufend - 50; part > buf && *part != '/'; --part) ; if (part != buf) { ++part; goto l_exit; } for (part = bufend - 50; part < bufend && *part != '/'; ++part) ; if (part != bufend) { return ++part; goto l_exit; } part = bufend - 50; l_exit: len = bufend - part; res = MEM_ALLOC(len); if (res) { memcpy(res, part, len); res[len - 1] = 0; } return res; } char* get_path_by_dentry(struct dentry* dentry, struct vfsmount* mnt, int* err, char** fname_part) { char *path, *buf; int pathlen, bufsz = PAGE_SIZE; while (1) { buf = MEM_ALLOC(bufsz); if (!buf) { if (err) *err = -ENOMEM; return NULL; } path = d_path_wrap(dentry, mnt, buf, bufsz); if (IS_ERR(path)) { if (-ENAMETOOLONG == PTR_ERR(path)) { bufsz *= 2; if (bufsz > m_config.max_fname_len) { if (fname_part) *fname_part = get_fname_part(buf, buf + bufsz / 2); if (err) *err = -ENAMETOOLONG; MEM_FREE(buf); return NULL; } MEM_FREE(buf); continue; } if (err) *err = PTR_ERR(path); MEM_FREE(buf); return NULL; } break; } pathlen = strlen(path); if (file_unlinked(dentry) && !strcmp(path + (pathlen - 10), " (deleted)")) { path[pathlen - 10] = 0; pathlen -= 10; } if (PAGE_SIZE == bufsz) { char* tmp = MEM_ALLOC(pathlen + 1); if (tmp) { memcpy(tmp, path, pathlen + 1); MEM_FREE(buf); buf = tmp; } else memmove(buf, path, pathlen + 1); } else memmove(buf, path, pathlen + 1); return buf; } static struct file __rcu *get_exec_file(struct mm_struct* mm) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) struct vm_area_struct* vma; vma = mm->mmap; while (vma) { if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) return vma->vm_file; vma = vma->vm_next; } #else return mm->exe_file; #endif return NULL; } int get_exec_path(struct task_struct* task, struct vfsmount** vfsmnt, struct dentry** dentry) { struct mm_struct* mm; struct file __rcu *exe_file; mm = get_task_mm(task); if (!mm) return -EINVAL; down_read(&mm->mmap_sem); exe_file = get_exec_file(mm); if (exe_file) { *dentry = exe_file->f_dentry; *vfsmnt = exe_file->f_vfsmnt; } up_read(&mm->mmap_sem); mm_put(mm); return 0; } int get_exec_info(struct task_struct __rcu *task, file_info* file) { struct mm_struct* mm; struct file __rcu *exe_file; int locked = 0; mm = get_task_mm(task); if (!mm) return -1; /* * FIXME: mmap/munmap problem. this function can be called in mmap/munmap * context. This code has mmap_sem already * locked. in this way down_read caused deadlock. workaround: * down_read_try_lock() * */ locked = down_read_trylock(&mm->mmap_sem); exe_file = get_exec_file(mm); if (exe_file) fill_file_info(exe_file->f_dentry, file); if (locked) up_read(&mm->mmap_sem); mm_put(mm); return exe_file ? 0 : -1; } char* get_file_from_userspace(const char __user *u_filename, file_info* info, char** filename) { #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)) struct path path; #else #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 48)) struct nameidata nd; #else struct dentry* dentry = NULL; #endif #endif char* k_path = NULL; *filename = NULL; /* Get kernel-space filename if user part is present */ if (!u_filename) return NULL; /* * Fill nameidata structure if the file exists. * If the file isn't exists, there is nothing to test. */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)) if (user_path(u_filename, &path)) return NULL; k_path = get_path_by_dentry(path.dentry, path.mnt, NULL, NULL); *filename = k_path; fill_file_info(path.dentry, info); path_put(&path); #else #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 48)) if (user_path_walk(u_filename, &nd)) return 0; k_path = get_path_by_dentry(GET_NAMEIDATA_PATH(nd).dentry, GET_NAMEIDATA_PATH(nd).mnt, NULL, NULL); *filename = k_path; fill_file_info(GET_NAMEIDATA_PATH(nd).dentry, info); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)) path_release(&nd); #endif #else dentry = namei(u_filename); if (IS_ERR(dentry)) return 0; k_path = get_path_by_dentry(dentry, NULL, NULL, NULL); *filename = k_path; fill_file_info(dentry, info); dput(dentry); #endif #endif return k_path; } void get_current_fs_root(struct vfsmount** rootmnt, struct dentry** root) { FS_LOCK(¤t->fs->lock); *rootmnt = mntget(get_cur_fs_rootmnt()); *root = dget(get_cur_fs_root()); FS_UNLOCK(¤t->fs->lock); } int same_as_current_fs_root(struct vfsmount* rootmnt, struct dentry* root) { int res; FS_LOCK(¤t->fs->lock); res = (rootmnt == get_cur_fs_rootmnt()) && (root == get_cur_fs_root()); FS_UNLOCK(¤t->fs->lock); return res; }
💾 Save Changes
Cancel
📤 Upload File
×
Select File
Upload
Cancel
➕ Create New
×
Type
📄 File
📁 Folder
Name
Create
Cancel
✎ Rename Item
×
Current Name
New Name
Rename
Cancel
🔐 Change Permissions
×
Target File
Permission (e.g., 0755, 0644)
0755
0644
0777
Apply
Cancel