Linux eyewebsolution.dnshostserver.in 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64
Apache
: 185.131.55.234 | : 216.73.216.36
674 Domain
5.6.40
omxrelocation
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
usr /
src /
file_protector-1.1-1524 /
[ HOME SHELL ]
Name
Size
Permission
Action
common
[ DIR ]
drwxr-xr-x
syscall_hooks
[ DIR ]
drwxr-xr-x
transport
[ DIR ]
drwxr-xr-x
Kbuild
3.71
KB
-rw-r--r--
Makefile
2.2
KB
-rw-r--r--
compat.c
5.74
KB
-rw-r--r--
compat.h
6.94
KB
-rw-r--r--
debug.h
3.56
KB
-rw-r--r--
dkms.conf
146
B
-rw-r--r--
memory.h
529
B
-rw-r--r--
module.c
1.86
KB
-rw-r--r--
module_ref.h
421
B
-rw-r--r--
module_rundown_protection.c
3.6
KB
-rw-r--r--
module_rundown_protection.h
743
B
-rw-r--r--
rundown_protection.c
4.2
KB
-rw-r--r--
rundown_protection.h
2.83
KB
-rw-r--r--
stringify.h
261
B
-rw-r--r--
task_info_map.c
19.07
KB
-rw-r--r--
task_info_map.h
1.92
KB
-rw-r--r--
tracepoints.c
3.02
KB
-rw-r--r--
tracepoints.h
299
B
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : task_info_map.c
/** @file @brief Process (aka task) info storage @details Copyright (c) 2017-2021 Acronis International GmbH @author Ivan Matveev (ivan.matveev@acronis.com) @since $Id: $ */ #include "task_info_map.h" #include "transport.h" #include "compat.h" #include "debug.h" #include "memory.h" #include <linux/mm.h> // get_task_exe_file() static task_info_map_t task_info_maps[MAX_TASK_INFO_MAP_SIZE] = {0}; const char *task_status_to_string(task_status_t status) { switch (status) { #define CASE_TS_RETURN(t) case TS_##t: return #t CASE_TS_RETURN(UNKNOWN); CASE_TS_RETURN(IGNORE); CASE_TS_RETURN(WHITE); CASE_TS_RETURN(BLACK); CASE_TS_RETURN(GREY); #undef CASE_TS_RETURN default: return "?"; } } static task_info_t *task_info_init(task_info_t *task_info, pid_t pid) { DPRINTF("task_info=%p pid=%i", task_info, pid); RB_CLEAR_NODE(&task_info->rb_node); task_info->pid = pid; atomic_set(&task_info->ref_cnt, 1); spin_lock_init(&task_info->spinlock); task_info->status = TS_UNKNOWN; /* struct path { struct vfsmount *mnt; struct dentry *dentry; }; */ task_info->exe_path = (struct path){}; task_info->is_exe_path_changed = true; INIT_LIST_HEAD(&task_info->exited_list_item); return task_info; } static task_info_t *task_info_new(pid_t pid) { task_info_t *task_info = mem_alloc0(sizeof(task_info_t)); if (task_info) { task_info_init(task_info, pid); } return task_info; } static task_info_t *task_info_ref(task_info_t *task_info) { atomic_inc(&task_info->ref_cnt); return task_info; } static void task_info_free(task_info_t *task_info) { DPRINTF("task_info=%p", task_info); // Note: 'path_put(&path={})' is safe path_put(&task_info->exe_path); mem_free(task_info); } static void task_info_unref(task_info_t *task_info) { DPRINTF("pid=%d ref_cnt=%d", task_info->pid, atomic_read(&task_info->ref_cnt)); if (atomic_dec_and_test(&task_info->ref_cnt)) { task_info_free(task_info); } } static int task_info_map_init(task_info_map_t *map) { spin_lock_init(&map->spinlock); map->root = RB_ROOT; spin_lock_init(&map->exited_list_spinlock); INIT_LIST_HEAD(&map->exited_list); atomic_set(&map->is_acquired, false); return 0; } void task_info_maps_init(void) { task_info_map_t *map; unsigned char i = 0; DPRINTF("task_info_maps_init"); for (i = 0; i < MAX_TASK_INFO_MAP_SIZE; i++) { map = &task_info_maps[i]; task_info_map_init(map); } } static void task_info_map_clear_exited_list(task_info_map_t *map) { for (;;) { task_info_t *task_info; spin_lock(&map->exited_list_spinlock); if (list_empty(&map->exited_list)) { spin_unlock(&map->exited_list_spinlock); return; } task_info = list_entry(map->exited_list.next, task_info_t, exited_list_item); if (task_info) { list_del_init(&task_info->exited_list_item); spin_unlock(&map->exited_list_spinlock); if (atomic_read(&task_info->ref_cnt) != 1) { DPRINTF("task info [%d] ref_cnf[%d] is not equal to 1 when clearing", task_info->pid, atomic_read(&task_info->ref_cnt)); } // undo 'inc' done for 'task_info_map.exited_list' task_info_unref(task_info); } else { spin_unlock(&map->exited_list_spinlock); } } } static void task_info_map_clear(task_info_map_t *map) { struct rb_root root; struct rb_node *node; task_info_map_clear_exited_list(map); spin_lock(&map->spinlock); root = map->root; map->root = RB_ROOT; spin_unlock(&map->spinlock); node = root.rb_node; while (node) { task_info_t *task_info; spin_lock(&map->spinlock); task_info = rb_entry(node, task_info_t, rb_node); rb_erase(&task_info->rb_node, &root); node = root.rb_node; spin_unlock(&map->spinlock); if (atomic_read(&task_info->ref_cnt) != 1) { DPRINTF("task info [%d] ref_cnf[%d] is not equal to 1 when clearing", task_info->pid, atomic_read(&task_info->ref_cnt)); } task_info_unref(task_info); } } void task_info_maps_clear(void) { task_info_map_t *map; unsigned char i = 0; DPRINTF("task_info_maps_clear"); for (i = 0; i < MAX_TASK_INFO_MAP_SIZE; i++) { map = &task_info_maps[i]; task_info_map_clear(map); } } // Assume that each transport only use it's unique valid map_id after acquiring unsigned char acquire_task_info_map(void) { unsigned char map_id = MAX_TASK_INFO_MAP_SIZE + 1; unsigned char i = 0; for (i = 0; i < MAX_TASK_INFO_MAP_SIZE; i++) { spin_lock(&task_info_maps[i].spinlock); if (!atomic_read(&task_info_maps[i].is_acquired)) { map_id = i; atomic_set(&task_info_maps[i].is_acquired, true); spin_unlock(&task_info_maps[i].spinlock); break; } spin_unlock(&task_info_maps[i].spinlock); } if (map_id < MAX_TASK_INFO_MAP_SIZE) { DPRINTF_LEVEL(LOG_LEVEL_DEBUG1, "Acquire task_info_map ok: %u", map_id); } else { EPRINTF("Failed to acquire task_info_map"); } return map_id; } void release_task_info_map(unsigned char map_id) { task_info_map_t *map; struct list_head task_info_clear_list; if (map_id >= MAX_TASK_INFO_MAP_SIZE) { return; } spin_lock(&task_info_maps[map_id].spinlock); if (!atomic_read(&task_info_maps[map_id].is_acquired)) { spin_unlock(&task_info_maps[map_id].spinlock); return; } INIT_LIST_HEAD(&task_info_clear_list); map = &task_info_maps[map_id]; atomic_set(&map->is_acquired, false); { struct rb_root root; struct rb_node *node; root = map->root; map->root = RB_ROOT; node = root.rb_node; while (node) { task_info_t *task_info = rb_entry(node, task_info_t, rb_node); rb_erase(&task_info->rb_node, &root); list_add_tail(&task_info->clear_list_item, &task_info_clear_list); node = root.rb_node; } } spin_unlock(&task_info_maps[map_id].spinlock); for (;;) { task_info_t *task_info; if (list_empty(&task_info_clear_list)) { break; } task_info = list_entry(task_info_clear_list.next, task_info_t, clear_list_item); if (task_info) { list_del_init(&task_info->clear_list_item); if (atomic_read(&task_info->ref_cnt) != 1) { DPRINTF("task info [%d] ref_cnf[%d] is not equal to 1 when clearing", task_info->pid, atomic_read(&task_info->ref_cnt)); } task_info_unref(task_info); } } task_info_map_clear_exited_list(map); DPRINTF_LEVEL(LOG_LEVEL_DEBUG1, "Release task_info_map: %u", map_id); } static task_info_t *task_info_lookup(task_info_map_t *map, pid_t pid) { struct rb_node *node; task_info_t *task_info = NULL; DPRINTF("pid=%d", pid); spin_lock(&map->spinlock); if (atomic_read(&map->is_acquired) == false) { spin_unlock(&map->spinlock); return NULL; } node = map->root.rb_node; while (node) { task_info_t *node_task_info = rb_entry(node, task_info_t, rb_node); pid_t node_pid = node_task_info->pid; if (pid < node_pid) { node = node->rb_left; } else if (pid > node_pid) { node = node->rb_right; } else { task_info = task_info_ref(node_task_info); break; } } spin_unlock(&map->spinlock); DPRINTF_RATELIMITED("task_info=%p pid=%d", task_info, pid); return task_info; } static task_info_t *task_info_map_insert(task_info_map_t *map, task_info_t *new_task_info) { pid_t pid = new_task_info->pid; struct rb_node *parent = NULL; struct rb_node **link; DPRINTF_RATELIMITED("new_task_info=%p pid=%i", new_task_info, pid); spin_lock(&map->spinlock); if (atomic_read(&map->is_acquired) == false) { spin_unlock(&map->spinlock); return NULL; } link = &(map->root.rb_node); while (*link) { task_info_t *node_task_info; pid_t node_pid; parent = *link; node_task_info = rb_entry(parent, task_info_t, rb_node); node_pid = node_task_info->pid; if (pid < node_pid) { link = &parent->rb_left; } else if (pid > node_pid) { link = &parent->rb_right; } else { // collision DPRINTF_RATELIMITED("collision"); task_info_ref(node_task_info); spin_unlock(&map->spinlock); return node_task_info; } } // do 'inc' for 'map->root' task_info_ref(new_task_info); rb_link_node(&new_task_info->rb_node, parent, link); rb_insert_color(&new_task_info->rb_node, &map->root); DPRINTF_RATELIMITED("inserted"); spin_unlock(&map->spinlock); return new_task_info; } // Warning: May block! static task_info_t *task_info_add(task_info_map_t *map, pid_t pid) { task_info_t *task_info; task_info_t *new_task_info; DPRINTF_RATELIMITED("pid=%d", pid); task_info = task_info_lookup(map, pid); if (task_info) { DPRINTF_RATELIMITED("pid=%i is already in the map (task_info=%p)", pid, task_info); return task_info; } new_task_info = task_info_new(pid); if (!new_task_info) { DPRINTF_RATELIMITED("out of memory"); return NULL; } task_info = task_info_map_insert(map, new_task_info); if (task_info != new_task_info) { // collision DPRINTF_RATELIMITED("collision"); task_info_unref(new_task_info); } return task_info; } static int task_info_map_del(task_info_map_t *map, pid_t pid) { task_info_t *task_info; DPRINTF("pid=%d", pid); task_info = task_info_lookup(map, pid); if (!task_info) { // task info may be deleted in task_info_map_clear_exited_list() // so here no need to print warning DPRINTF("pid=%d is missing in the map", pid); return -ENOENT; } spin_lock(&map->spinlock); if (map->root.rb_node != NULL) { rb_erase(&task_info->rb_node, &map->root); } spin_unlock(&map->spinlock); // undo 'inc' done for 'map->root' task_info_unref(task_info); // undo 'inc' done in 'task_info_lookup()' task_info_unref(task_info); DPRINTF("pid=%d", pid); return 0; } static void task_info_map_remove(task_info_map_t *map, task_info_t *task_info) { spin_lock(&map->spinlock); if (map->root.rb_node != NULL) { rb_erase(&task_info->rb_node, &map->root); } if (atomic_read(&task_info->ref_cnt) >= 2) { // undo 'inc' done for 'map->root' task_info_unref(task_info); } spin_unlock(&map->spinlock); } int task_info_map_del_by_map_id(unsigned char map_id, pid_t pid) { task_info_map_t *map = NULL; int ret = 0; if (map_id >= MAX_TASK_INFO_MAP_SIZE) { return ENOENT; } if (!atomic_read(&task_info_maps[map_id].is_acquired)) { return ENOENT; } map = &task_info_maps[map_id]; ret = task_info_map_del(map, pid); return ret; } static task_info_t *get_task_info_by_map_id(unsigned char map_id, pid_t pid) { task_info_map_t *map = NULL; task_info_t *task_info = NULL; if (map_id >= MAX_TASK_INFO_MAP_SIZE) { return NULL; } if (!atomic_read(&task_info_maps[map_id].is_acquired)) { return NULL; } map = &task_info_maps[map_id]; task_info = task_info_lookup(map, pid); return task_info; } // Warning: May block! int task_info_status_set_by_map_id(unsigned char map_id, pid_t pid, task_status_t status) { task_info_t *task_info = NULL; task_info_map_t *map = NULL; DPRINTF_LEVEL(LOG_LEVEL_DEBUG1, "map_id:%u pid=%i status=%i/%s", map_id, pid, status, task_status_to_string(status)); if (map_id >= MAX_TASK_INFO_MAP_SIZE) { return ENOENT; } if (!atomic_read(&task_info_maps[map_id].is_acquired)) { return ENOENT; } map = &task_info_maps[map_id]; task_info = task_info_add(map, pid); if (!task_info) { WPRINTF("'%s(pid=%i)' failure", "task_info_add", pid); return -ENOMEM; } spin_lock(&task_info->spinlock); task_info->status = status; spin_unlock(&task_info->spinlock); task_info_unref(task_info); return 0; } void task_info_map_on_exit_event(pid_t tgid, pid_t pid) { unsigned char i = 0; task_info_t *task_info = NULL; task_info_map_t *map = NULL; (void) tgid; for (i = 0; i < MAX_TASK_INFO_MAP_SIZE; i++) { task_info = NULL; if (!atomic_read(&task_info_maps[i].is_acquired)) { continue; } map = &task_info_maps[i]; task_info = task_info_lookup(map, pid); if (!task_info) { DPRINTF("%u:%u is missing in 'map'", tgid, pid); } else { spin_lock(&map->exited_list_spinlock); if (!list_empty(&task_info->exited_list_item)) { DPRINTF("%u:%u is already in 'exited list'", tgid, pid); } else { // do 'inc' for 'map->exited_list' task_info_ref(task_info); list_add_tail(&task_info->exited_list_item, &map->exited_list); DPRINTF("%u:%u task_info=%p is added to 'exited list'", tgid, pid, task_info); } spin_unlock(&map->exited_list_spinlock); task_info_unref(task_info); task_info_map_remove(map, task_info); } } } void task_info_map_clear_exited_list_by_map_id(unsigned char map_id) { task_info_map_t *map = NULL; if (map_id >= MAX_TASK_INFO_MAP_SIZE) { return; } if (!atomic_read(&task_info_maps[map_id].is_acquired)) { return; } map = &task_info_maps[map_id]; task_info_map_clear_exited_list(map); return; } int check_exec_with_task_info(pid_t tgid, struct path exe_path) { unsigned char i = 0; task_info_t *task_info = NULL; task_info_map_t *map = NULL; bool is_exe_path_changed = false; for (i = 0; i < MAX_TASK_INFO_MAP_SIZE; i++) { task_info = NULL; if (!atomic_read(&task_info_maps[i].is_acquired)) { continue; } map = &task_info_maps[i]; task_info = task_info_add(map, tgid); if (task_info) { struct path old_path = (struct path){}; spin_lock(&task_info->spinlock); if (path_equal(&task_info->exe_path, &exe_path)) { } else { task_info->is_exe_path_changed = true; old_path = task_info->exe_path; task_info->exe_path = exe_path; path_get(&task_info->exe_path); } if(task_info->is_exe_path_changed){ is_exe_path_changed = true; } spin_unlock(&task_info->spinlock); // it's ok to call path_put when old_path == {0} path_put(&old_path); // shouldn't call under spinlock, because might sleep task_info_unref(task_info); } else { EPRINTF("Failed to add task info"); } } if (is_exe_path_changed) { return 1; } return 0; } static bool msg_should_skip(task_info_t *task_info, msg_type_img_t msg_type) { bool ret = false; task_status_t status; if (msg_type == MT_EXEC) { } else if (msg_type == MT_EXIT || msg_type == MT_FORK || msg_type == MT_FILE_PRE_CREATE || msg_type == MT_FILE_CREATE_EX || msg_type == MT_PRE_RENAME_EX || msg_type == MT_RENAME_EX || msg_type == MT_RENAME || msg_type == MT_PRE_UNLINK_EX || msg_type == MT_UNLINK_EX || msg_type == MT_UNLINK) { // for event in EXIT, FORK, CREATE, RENAME and UNLINK, always send } else { spin_lock(&task_info->spinlock); status = task_info->status; spin_unlock(&task_info->spinlock); // For event not in EXIT, FORK, CREATE, RENAME and UNLINK, check status is TS_WHITE or TS_IGNORE if (status == TS_IGNORE || status == TS_WHITE) { ret = true; } } return ret; } bool is_exe_path_changed(task_info_t *task_info) { struct file *exe_file; struct path exe_path; bool ret = false; exe_file = get_task_exe_file_compat(current); if (!exe_file) { return false; } path_get(&exe_file->f_path); exe_path = exe_file->f_path; fput(exe_file); spin_lock(&task_info->spinlock); if (!path_equal(&task_info->exe_path, &exe_path)) { ret = true; } spin_unlock(&task_info->spinlock); path_put(&exe_path); return ret; } bool sys_call_fs_events_should_skip(pid_t pid, uint64_t events_mask) { unsigned char i = 0; task_info_t *task_info = NULL; task_info_map_t *map = NULL; bool ret = true; for (i = 0; i < MAX_TASK_INFO_MAP_SIZE; i++) { msg_type_img_t msg_type; task_info = NULL; if (!atomic_read(&task_info_maps[i].is_acquired)) { continue; } map = &task_info_maps[i]; task_info = task_info_lookup(map, pid); if (!task_info) { return false; } if (is_exe_path_changed(task_info)) { task_info_unref(task_info); return false; } for (msg_type = MT_EXEC; msg_type < MT_MAX; msg_type++) { uint64_t event_mask = MSG_TYPE_TO_EVENT_MASK(msg_type); if (event_mask & events_mask) { if (!msg_should_skip(task_info, msg_type)) { ret = false; break; } } } task_info_unref(task_info); if (!ret) { break; } } return ret; } static bool should_send(unsigned char map_id, msg_type_img_t msg_type) { bool ret = true; task_info_t *task_info = NULL; task_status_t status; task_info = get_task_info_by_map_id(map_id, current->tgid); if (task_info == NULL) { return false; } if (msg_type == MT_EXEC) { spin_lock(&task_info->spinlock); if (task_info->is_exe_path_changed) { task_info->is_exe_path_changed = false; } else { ret = false; } spin_unlock(&task_info->spinlock); } else if (msg_type == MT_EXIT || msg_type == MT_FORK || msg_type == MT_FILE_PRE_CREATE || msg_type == MT_FILE_CREATE_EX || msg_type == MT_PRE_RENAME_EX || msg_type == MT_RENAME_EX || msg_type == MT_RENAME || msg_type == MT_PRE_UNLINK_EX || msg_type == MT_UNLINK_EX || msg_type == MT_UNLINK) { // for event in EXIT, FORK, CREATE, RENAME and UNLINK, always send } else { spin_lock(&task_info->spinlock); status = task_info->status; spin_unlock(&task_info->spinlock); // For event not in EXIT, FORK, CREATE, RENAME and UNLINK, check status is TS_WHITE or TS_IGNORE if (status == TS_IGNORE || status == TS_WHITE) { ret = false; } } task_info_unref(task_info); return ret; } void get_should_send_task_info_map_ids(bool *should_send_map_ids, msg_type_img_t msg_type) { int i; for (i = 0; i < MAX_TASK_INFO_MAP_SIZE; i++) { should_send_map_ids[i] = false; if (should_send(i, msg_type)) { should_send_map_ids[i] = true; } } }
Close