opt
/
kaspersky
/
kav4fs
/
src
/
kernel
➕ New
📤 Upload
✎ Editing:
kernel.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" typedef struct { file_info file; struct list_head list; } file_entry; typedef struct { pid_t pid; file_info file; struct list_head list; } proc_entry; static void monitor_finit_trusted(void); static lock_declare(trusted_lock); static KLIST_HEAD(trusted_files); static KLIST_HEAD(trusted_procs); monitor_config m_config; void Monitor_kernel_init(void) { lock_init(&trusted_lock, "kavmonitor kernel"); KINIT_LIST_HEAD(&trusted_files); m_config.cache_enable = 0; } void Monitor_kernel_finit(void) { monitor_finit_trusted(); Monitor_cache_stop(); lock_finit(&trusted_lock); } void monitor_finit_trusted(void) { proc_entry* proc; file_entry* file; struct list_head* tmp; again: write_lock(&trusted_lock); list_for_each(tmp, &trusted_files) { file = list_entry(tmp, file_entry, list); list_del(&file->list); write_unlock(&trusted_lock); MEM_FREE(file); goto again; } again1: list_for_each(tmp, &trusted_procs) { proc = list_entry(tmp, proc_entry, list); list_del(&proc->list); write_unlock(&trusted_lock); MEM_FREE(proc); write_lock(&trusted_lock); goto again1; } write_unlock(&trusted_lock); } int Monitor_kernel_register_file(const file_info* file) { file_entry* file_; struct list_head* tmp; write_lock(&trusted_lock); list_for_each(tmp, &trusted_files) { file_ = list_entry(tmp, file_entry, list); if (FILE_EQUAL(&file_->file, file)) { write_unlock(&trusted_lock); return 0; } } write_unlock(&trusted_lock); file_ = (file_entry*)MEM_ALLOC(sizeof(file_entry)); if (!file_) { PRN("Kernel memory allocation error"); return ENOMEM; } DEBUG_MSG("Register ino=%d dev=%d", (int)file->ino, (int)file->dev); memcpy(&file_->file, file, sizeof(file_info)); write_lock(&trusted_lock); list_add(&file_->list, &trusted_files); write_unlock(&trusted_lock); return 0; } int Monitor_kernel_register_proc(pid_t pid, const file_info* file) { proc_entry* proc; struct list_head* tmp; write_lock(&trusted_lock); list_for_each(tmp, &trusted_procs) { proc = list_entry(tmp, proc_entry, list); if (proc->pid == pid) { write_unlock(&trusted_lock); return 0; } } write_unlock(&trusted_lock); proc = (proc_entry*)MEM_ALLOC(sizeof(proc_entry)); if (!proc) { PRN("Kernel memory allocation error"); return ENOMEM; } DEBUG_MSG("Register pid=%d ino=%d dev=%d", (int)pid, (int)file->ino, (int)file->dev); memcpy(&proc->file, file, sizeof(file_info)); proc->pid = pid; write_lock(&trusted_lock); list_add(&proc->list, &trusted_procs); write_unlock(&trusted_lock); return 0; } void Monitor_kernel_unregister_file(const file_info* file) { struct list_head* tmp; file_entry* file_ = NULL; int need_free = 0; write_lock(&trusted_lock); list_for_each(tmp, &trusted_files) { file_ = list_entry(tmp, file_entry, list); if (FILE_EQUAL(&file_->file, file)) { list_del(&file_->list); need_free = 1; DEBUG_MSG("Register ino=%d dev=%d", (int)file->ino, (int)file->dev); break; } } write_unlock(&trusted_lock); if (need_free) { MEM_FREE(file_); } } void Monitor_kernel_unregister_proc(pid_t pid) { struct list_head* tmp; proc_entry* proc = NULL; int need_free = 0; write_lock(&trusted_lock); list_for_each(tmp, &trusted_procs) { proc = list_entry(tmp, proc_entry, list); if (proc->pid == pid) { list_del(&proc->list); need_free = 1; DEBUG_MSG("Unregister pid=%d", pid); break; } } write_unlock(&trusted_lock); if (need_free) { MEM_FREE(proc); } } static int monitor_kernel_trusted_file(const file_info* file) { struct list_head* tmp; file_entry* file_; // DEBUG_MSG("%s: dev=%d ino=%d IN",__FUNCTION__,(int)file->dev, (int)file->ino); list_for_each(tmp, &trusted_files) { file_ = list_entry(tmp, file_entry, list); if (FILE_EQUAL(&file_->file, file)) { // DEBUG_MSG("%s: dev=%d ino=%d trusted",__FUNCTION__,(int)file->dev, // (int)file->ino); return 1; } } // DEBUG_MSG("%s: dev=%d ino=%d OUT",__FUNCTION__,(int)file->dev, // (int)file->ino); return 0; } int Monitor_kernel_trusted_file(const file_info* file) { int ret; read_lock(&trusted_lock); ret = monitor_kernel_trusted_file(file); read_unlock(&trusted_lock); return ret; } int Monitor_kernel_trusted_proc(pid_t pid, const file_info* file) { struct list_head* tmp; proc_entry* proc; int ret = 0; // DEBUG_MSG("%s: pid=%d dev=%d ino=%d IN",__FUNCTION__,(int)pid, (int)file->dev, // (int)file->ino); read_lock(&trusted_lock); list_for_each(tmp, &trusted_procs) { proc = list_entry(tmp, proc_entry, list); // if (FILE_EQUAL(&proc->file, file) && proc->pid == pid){ /* we check only pid, because the registered pid can execute another binary * that should also have access to files */ if (proc->pid == pid) { read_unlock(&trusted_lock); // DEBUG_MSG("%s: pid=%d dev=%d ino=%d trusted",__FUNCTION__,(int)pid, // (int)file->dev, (int)file->ino); return 1; } } ret = monitor_kernel_trusted_file(file); read_unlock(&trusted_lock); // DEBUG_MSG("%s: pid=%d dev=%d ino=%d OUT",__FUNCTION__,(int)pid, // (int)file->dev, (int)file->ino); return ret; } #if defined(__FreeBSD__) int Monitor_kernel_check_file(uid_t uid, gid_t gid, pid_t pid, const char* filename, const file_info* info, const file_info_ex* info_ex, enum FileOpType f_op, int flags, int* err) { u_short queue_id; PackedBuffer req_buff; enum FileAccessType answer = FILE_ACCESS_ACCEPT; int block = (f_op == FILE_OPEN_OPER) ? 0 : 1; *err = 0; if (m_config.cache_enable) { if ((f_op == FILE_CLOSE_OPER)) { Monitor_cache_del(info->dev, info->ino); } else { const file_info* cache_info = Monitor_cached(info->dev, info->ino); if (cache_info) { if (cache_info->size != info->size || info->n_links > 1 || !timespec_equal(&cache_info->m_time, &info->m_time) || !timespec_equal(&cache_info->c_time, &info->c_time)) { Monitor_cache_del(info->dev, info->ino); } else return 0; } } } queue_id = Monitor_queue_get_id(); DEBUG_MSG("%s: pid=%d queue_id=%d Scanning of filename=%s has been started", __FUNCTION__, pid, queue_id, filename); if (1 == m_config.version) { MakeCheckFileReq(&req_buff, uid, gid, pid, queue_id, filename, f_op, flags, info->dev, info->ino); } else { MakeCheckFileReq2(&req_buff, m_config.version, uid, gid, pid, queue_id, filename, f_op, flags, info->dev, info->ino, info->m_time.tv_sec, info->size, info_ex->owner_uid, info_ex->file_mode, 0, info_ex->fstypename); } *err = Monitor_queue_add(queue_id, block, &req_buff, &answer); DEBUG_MSG( "%s: pid=%d queue_id=%d Scanning of filename=%s has been done answer=%d", __FUNCTION__, pid, queue_id, filename, answer); if (*err) return *err; if (answer == FILE_ACCESS_ACCEPT && m_config.cache_enable && info->n_links == 1) { Monitor_cache_add(info); } return (answer == FILE_ACCESS_ACCEPT || answer == FILE_ACCESS_NO_CHECK) ? 0 : EACCES; } int Monitor_kernel_check_file_sign(uid_t uid, gid_t gid, const char* filename) { u_short queue_id; PackedBuffer req_buff; int err = 0; enum FileAccessType answer = FILE_ACCESS_ACCEPT; queue_id = Monitor_queue_get_id(); if (1 == m_config.version) MakeCheckSignReq(&req_buff, uid, gid, queue_id, filename); else MakeCheckSignReq2(&req_buff, m_config.version, uid, gid, queue_id, filename); err = Monitor_queue_add(queue_id, 0, &req_buff, &answer); if (err) return 0; return (answer == FILE_ACCESS_ACCEPT); } #elif defined(__linux__) int Monitor_kernel_check_file(const file_info* info, check_req_data_t* reqd, int* err) { u_short queue_id; enum FileAccessType answer = FILE_ACCESS_ACCEPT; int block = (reqd->file_op_type == FILE_OPEN_OPER) ? 0 : 1; *err = 0; if (m_config.cache_enable && !is_cache_disabled_for(reqd->vfsmnt)) { if ((reqd->file_op_type == FILE_CLOSE_OPER)) { Monitor_cache_del(info->dev, info->ino); barrier(); } else { const file_info* cache_info = Monitor_cached(info->dev, info->ino); if (cache_info) { if (cache_info->size != info->size || info->n_links > 1 || !timespec_equal(&cache_info->m_time, &info->m_time) || !timespec_equal(&cache_info->c_time, &info->c_time)) { Monitor_cache_del(info->dev, info->ino); barrier(); } else return 0; } } } queue_id = Monitor_queue_get_id(); // DEBUG_MSG("%s: pid=%d queue_id=%d Scanning of filename=%s has been // started",__FUNCTION__,reqd->pid,queue_id,reqd->filename); *err = Monitor_queue_add(queue_id, block, reqd, &answer); // DEBUG_MSG("%s: pid=%d queue_id=%d Scanning of filename=%s has been done // answer=%d",__FUNCTION__, // reqd->pid,queue_id,reqd->filename,answer); if (*err) return *err; if (answer == FILE_ACCESS_ACCEPT && m_config.cache_enable && info->n_links == 1) { Monitor_cache_add(info); } return (answer == FILE_ACCESS_ACCEPT || answer == FILE_ACCESS_NO_CHECK) ? 0 : -EACCES; } int Monitor_kernel_check_file_sign(uid_t uid, gid_t gid, struct vfsmount* vfsmnt, struct dentry* dentry) { u_short queue_id; int err = 0; enum FileAccessType answer = FILE_ACCESS_ACCEPT; check_req_data_t* reqd; reqd = MEM_ALLOC(sizeof(*reqd)); if (!reqd) return 0; fill_check_req_common_fields(reqd, CHECK_SIGN, get_current_euid(), get_current_egid(), vfsmnt, dget_parent(dentry), dentry->d_name.name); queue_id = Monitor_queue_get_id(); err = Monitor_queue_add(queue_id, 0, reqd, &answer); check_req_queue_put(reqd); return err ? 0 : (answer == FILE_ACCESS_ACCEPT); } #endif /*__linux__*/
💾 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