ÿØÿà JFIF  ` ` ÿþš 403 WEBHELL REBORN
403 WEBHELL REBORN
Server : Apache
System : Linux cloud.heroica.com.br 4.18.0-553.36.1.el8_10.x86_64 #1 SMP Wed Jan 22 03:07:54 EST 2025 x86_64
User : farolpborg ( 1053)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /usr/src/file_protector-1.1-1505/transport/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

Buat Folder Baru:
Buat File Baru:

Current File : //usr/src/file_protector-1.1-1505/transport/message.c
/**
@file
@brief    kernel/userspace transport messages
@details  Copyright (c) 2017-2021 Acronis International GmbH
@author   Mikhail Krivtsov (mikhail.krivtsov@acronis.com)
@since    $Id: $
*/

#include "message.h"

#include "compat.h"
#include "debug.h"
#include "memory.h"
#include "task_info_map.h"

#include <linux/file.h>		// fput()
#include <linux/fs_struct.h>	// get_fs_root()
#include <linux/mm.h>		// get_task_exe_file()

const char* msg_type_to_string(msg_type_t type)
{
	switch (type)
	{
#define CASE_MT_RETURN(t) case MT_##t: return #t
	CASE_MT_RETURN(HELLO);
	CASE_MT_RETURN(PONG);
	CASE_MT_RETURN(EXEC);
	CASE_MT_RETURN(EXIT);
	CASE_MT_RETURN(FORK);
	CASE_MT_RETURN(DIR_OPEN);
	CASE_MT_RETURN(DIR_WRITE);
	CASE_MT_RETURN(DIR_CLOSE);
	CASE_MT_RETURN(FILE_PRE_CREATE);
	CASE_MT_RETURN(FILE_CREATE);
	CASE_MT_RETURN(FILE_PRE_OPEN);
	CASE_MT_RETURN(FILE_OPEN);
	CASE_MT_RETURN(FILE_PRE_WRITE);
	CASE_MT_RETURN(FILE_WRITE);
	CASE_MT_RETURN(FILE_CLOSE);
	CASE_MT_RETURN(PRE_RENAME);
	CASE_MT_RETURN(RENAME);
	CASE_MT_RETURN(PRE_UNLINK);
	CASE_MT_RETURN(UNLINK);
	CASE_MT_RETURN(FILE_PRE_CLOSE);
	default: return "?";
	}
}

const char* action_type_to_string(action_type_t type)
{
	switch (type)
	{
#define CASE_AT_RETURN(t) case AT_##t: return #t
	CASE_AT_RETURN(PING);
	CASE_AT_RETURN(PID_SET_ST);
	CASE_AT_RETURN(PID_DEL);
	CASE_AT_RETURN(GET_PID_INFO);
	CASE_AT_RETURN(GET_FS_ROOT);
	CASE_AT_RETURN(GET_VERSION);
	CASE_AT_RETURN(OPEN_FILE_FROM_MSG);
	CASE_AT_RETURN(OPEN_FILE_BY_PATH);
	CASE_AT_RETURN(ENABLE_EVENTS);
	CASE_AT_RETURN(DISABLE_EVENTS);
	default: return "?";
	}
}

const char* return_type_to_string(return_type_t type)
{
	switch (type)
	{
#define CASE_RT_RETURN(t) case RT_##t: return #t
	CASE_RT_RETURN(ERROR);
	CASE_RT_RETURN(PID_INFO);
	CASE_RT_RETURN(FS_ROOT);
	CASE_RT_RETURN(OPENED_FILE);
	default: return "?";
	}
}

static void msg_free(msg_t * msg)
{
	DPRINTF("msg=%p img_size=%zu type=%i/%s id=%llX reply=%i",
			msg, msg->img_size,
			MSG_TYPE(msg), msg_type_to_string(MSG_TYPE(msg)),
			MSG_ID(msg), MSG_REPLY(msg));
	mem_free(msg);
}

msg_t *msg_ref(msg_t *msg)
{
	atomic_inc(&msg->ref_cnt);
	DPRINTF("msg=%p ref_cnt=%i", msg, atomic_read(&msg->ref_cnt));
	return msg;
}

void msg_unref(msg_t *msg)
{
	DPRINTF("msg=%p ref_cnt=%i", msg, atomic_read(&msg->ref_cnt));
	if (atomic_dec_and_test(&msg->ref_cnt)) {
		msg_free(msg);
	}
}

msg_t *msg_reply_wait_count_inc(msg_t *msg)
{
	msg_ref(msg);
	atomic_inc(&msg->reply_wait_count);
	DPRINTF("msg=%p reply_wait_count=%i", msg, atomic_read(&msg->reply_wait_count));
	return msg;
}

void msg_reply_wait_count_dec(msg_t *msg)
{
	DPRINTF("msg=%p reply_wait_count=%i", msg, atomic_read(&msg->reply_wait_count));
	if (atomic_dec_and_test(&msg->reply_wait_count)) {
		wake_up(&msg->wait_queue);
	}
	msg_unref(msg);
}

msg_sized_t* msg_varsized_init(msg_varsized_t *msg, size_t msg_img_size) {
	msg_sized_t* smsg;
	msg->on_heap = msg_img_size > MSG_MAX_SMALL_PAYLOAD_SIZE;
	if (msg->on_heap) {
		msg->data.heap.ptr = msg_sized_new(msg_img_size);
	}

	smsg = MSG_VARSIZED_GET_SIZED(msg);
	if (smsg) {
		smsg->img_size = msg_img_size;
	}

	return smsg;
}

void msg_varsized_uninit(msg_varsized_t *msg) {
	if (msg->on_heap) {
		msg_sized_free(msg->data.heap.ptr);
	}
}

static msg_t *msg_init(msg_t *msg, size_t msg_img_size)
{
	atomic_set(&msg->ref_cnt, 1);
	atomic_set(&msg->reply_wait_count, 0);
	init_waitqueue_head(&msg->wait_queue);
	msg->img_size = msg_img_size;
	msg->interrupted = false;
	msg->block = false;
	thread_safe_path_init(&msg->path);
	return msg;
}

msg_sized_t *msg_sized_new(size_t msg_img_size)
{
	size_t msg_size = sizeof(msg_sized_t) + msg_img_size;
	msg_sized_t *msg = mem_alloc(msg_size);
	if (msg) {
		msg->img_size = msg_img_size;
	}
	return msg;
}

msg_t *msg_new(size_t msg_img_size)
{
	size_t msg_size = sizeof(msg_t) + msg_img_size;
	msg_t *msg = mem_alloc0(msg_size);
	if (msg) {
		msg_init(msg, msg_img_size);
	}
	DPRINTF("msg=%p msg_size=%zu msg_img_size=%zu", msg, msg_size, msg_img_size);
	return msg;
}

msg_t *msg_new_nowait(size_t msg_img_size)
{
	size_t msg_size = sizeof(msg_t) + msg_img_size;
	msg_t *msg = mem_alloc0_nowait(msg_size);
	if (msg) {
		msg_init(msg, msg_img_size);
	}
	DPRINTF("msg=%p msg_size=%zu msg_img_size=%zu", msg, msg_size, msg_img_size);
	return msg;
}

msg_t *msg_new_type(size_t msg_img_size, msg_type_t type)
{
	msg_t *msg = msg_new(msg_img_size);
	if (msg) {
		msg_img_t *msg_img = MSG_IMG(msg);
		msg_img->type = type;
	}
	DPRINTF("msg=%p type=%i/%s", msg, type, msg_type_to_string(type));
	return msg;
}

msg_t *msg_new_type_nowait(size_t msg_img_size, msg_type_t type)
{
	msg_t *msg = msg_new_nowait(msg_img_size);
	if (msg) {
		msg_img_t *msg_img = MSG_IMG(msg);
		msg_img->type = type;
	}
	DPRINTF("msg=%p type=%i/%s", msg, type, msg_type_to_string(type));
	return msg;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

msg_t *hello_msg_new(void)
{
	static const char hello[] = "hello";

	size_t hello_img_size = sizeof(hello_img_t) + sizeof(hello);
	size_t msg_img_size = sizeof(msg_img_t) + hello_img_size;

	msg_t *msg = msg_new_type(msg_img_size, MT_HELLO);
	if (msg) {
		msg_img_t *msg_img = MSG_IMG(msg);
		hello_img_t *hello_img = IMG_PAYLOAD(msg_img);
		memcpy(hello_img->payload, hello, sizeof(hello));
	}
	DPRINTF("msg=%p", msg);
	return msg;
}

// assuming correct 'ping_msg'
msg_t *pong_msg_new(msg_sized_t *ping_msg)
{
	msg_img_t *ping_msg_img = MSG_IMG(ping_msg);
	ping_img_t *ping_img = IMG_PAYLOAD(ping_msg_img);
	ping_pong_sequence_t sequence = ping_img->sequence;
	size_t ping_img_size = ping_msg->img_size - sizeof(msg_img_t);
	size_t payload_size = ping_img_size - sizeof(ping_img_t);

	size_t pong_img_size = sizeof(pong_img_t) + payload_size;
	size_t msg_img_size = sizeof(msg_img_t) + pong_img_size;

	msg_t *msg = msg_new_type(msg_img_size, MT_PONG);
	if (msg) {
		msg_img_t *msg_img = MSG_IMG(msg);
		pong_img_t *pong_img = IMG_PAYLOAD(msg_img);
		pong_img->sequence = sequence;
		if (payload_size) {
			memcpy(pong_img->payload, ping_img->payload,
					payload_size);
		}
	}
	DPRINTF("msg=%p payload_size=%zu", msg, payload_size);
	return msg;
}

static int path_to_string(char **p_buf, const char **p_start, struct path *path)
{
	char *buf;
	char *start;
	int ret;

	buf = mem_alloc(PATH_MAX);
	if (!buf) {
		return -ENOMEM;
	}
	*p_buf = buf;

	start = d_path(path, buf, PATH_MAX);
	if (IS_ERR(start)) {
		ret = PTR_ERR(start);
		WPRINTF("'d_path()' failure %i", ret);
		mem_free(buf);
		return ret;
	}
	*p_start = start;
	return 0;
}

enum check_exec_code {
	CEC_WAS,
	CEC_WAS_NOT,
	CEC_NEW_PROC
};

static enum check_exec_code check_exec(pid_t tgid, struct path exe_path)
{
	task_info_t *task_info;
	enum check_exec_code ret;
	struct path old_path;

	task_info = task_info_lookup(tgid);
	if (!task_info) {
		task_info = task_info_get(tgid);
		if (task_info) {
			spin_lock(&task_info->spinlock);

			task_info->status = TS_GREY;
			old_path = task_info->exe_path;
			task_info->exe_path = exe_path;
			path_get(&task_info->exe_path);

			spin_unlock(&task_info->spinlock);
			path_put(&old_path); // shouldn't call under spinlock, because might sleep

			task_info_unref(task_info);
		}
		ret = CEC_NEW_PROC;
	} else {
		spin_lock(&task_info->spinlock);
		if ((task_info->status == TS_IGNORE) || (path_equal(&task_info->exe_path, &exe_path))) {
			spin_unlock(&task_info->spinlock);
			ret = CEC_WAS_NOT;
		} else {
			task_info->status = TS_GREY;
			old_path = task_info->exe_path;
			task_info->exe_path = exe_path;
			path_get(&task_info->exe_path);

			spin_unlock(&task_info->spinlock);
			path_put(&old_path); // shouldn't call under spinlock, because might sleep
			ret = CEC_WAS;
		}
		task_info_unref(task_info);
	}

	return ret;
}

static msg_t *heur_exec_msg_new(void)
{
	struct path exe_path;
	struct file *exe_file;
	char *path_buf = NULL;
	const char *path_start = NULL;
	size_t path_size;
	size_t exec_img_size;
	size_t msg_img_size;
	int ret;
	msg_t *msg;
	enum check_exec_code check_code;
	pid_t ptgid = 0, ppid = 0;
	pid_t tgid, pid;

	tgid = current->tgid;
	pid = current->pid;

	if (TS_IGNORE == task_info_status_get(tgid)
	|| (pid != tgid && TS_IGNORE == task_info_status_get(pid))) {
		return NULL;
	}

	exe_file = get_task_exe_file_compat(current);
	// Note: kernel's threads do not have 'exe_file'
	if (!exe_file) {
		return NULL;
	}
	path_get(&exe_file->f_path);
	exe_path = exe_file->f_path;
	fput(exe_file);

	check_code = check_exec(tgid, exe_path);
	if (check_code == CEC_WAS_NOT) {
		path_put(&exe_path);
		return NULL;
	}

	ret = path_to_string(&path_buf, &path_start, &exe_path);
	path_put(&exe_path);
	if (ret) {
		return NULL;
	}

	if (current->real_parent) {
		ptgid = current->real_parent->tgid;
		ppid = current->real_parent->pid;
	}

	path_size = path_start ? strlen(path_start) + 1 : 0;
	exec_img_size = sizeof(exec_img_t) + path_size;
	msg_img_size = sizeof(msg_img_t) + exec_img_size;
	msg = msg_new_type(msg_img_size, MT_EXEC);
	if (msg) {
		msg_img_t *msg_img = MSG_IMG(msg);
		exec_img_t *exec_img = IMG_PAYLOAD(msg_img);
		/*
		 * userspace kernel
		 * getpid()  task->tgid
		 * gettid()  task->pid
		 */
		exec_img->pid = tgid;
		exec_img->tid = pid;
		exec_img->ppid = ptgid;
		exec_img->ptid = ppid;
		exec_img->sure = check_code == CEC_WAS;
		if (path_start) {
			memcpy(exec_img->path, path_start, path_size);
		}
	}

	mem_free(path_buf);
	return msg;
}

static msg_sized_t* msg_varsized_init_type(msg_varsized_t *msg, size_t msg_img_size, return_type_t type) {
	msg_sized_t* smsg = msg_varsized_init(msg, msg_img_size);
	if (smsg) {
		MSG_TYPE(smsg) = type;
	}

	return smsg;
}

int pid_info_return_msg_new(msg_varsized_t *msg, pid_t nr)
{
	struct path exe_path;
	struct pid *pid;
	struct task_struct *task;
	struct file *exe_file;
	char *path_buf = NULL;
	const char *path_start = NULL;
	pid_t task_tgid;
	pid_t task_pid;
	size_t path_size;
	size_t pid_info_img_size;
	size_t msg_img_size;
	msg_sized_t *smsg;
	int ret;

	pid = find_get_pid(nr);
	task = get_pid_task(pid, PIDTYPE_PID);
	put_pid(pid);
	if (!task) {
		WPRINTF("'%s(%i)' failure", "get_pid_task", nr);
		ret = -ENOENT;
		goto out;
	}
	task_tgid = task->tgid;
	task_pid = task->pid;
	exe_file = get_task_exe_file_compat(task);
	put_task_struct(task);
	// Note: kernel's threads do not have 'exe_file'
	if (exe_file) {
		path_get(&exe_file->f_path);
		exe_path = exe_file->f_path;
		fput(exe_file);
		ret = path_to_string(&path_buf, &path_start, &exe_path);
		path_put(&exe_path);
		if (ret) {;
			goto out;
		}
	}

	path_size = path_start ? strlen(path_start) + 1 : 0;
	pid_info_img_size = sizeof(pid_info_img_t) + path_size;
	msg_img_size = sizeof(msg_img_t) + pid_info_img_size;
	smsg = msg_varsized_init_type(msg, msg_img_size, RT_PID_INFO);
	if (smsg) {
		msg_img_t *msg_img = MSG_IMG(smsg);
		pid_info_img_t *pid_info_img = IMG_PAYLOAD(msg_img);
		/*
		 * userspace kernel
		 * getpid()  task->tgid
		 * gettid()  task->pid
		 */
		pid_info_img->pid = task_tgid;
		pid_info_img->tid = task_pid;
		if (path_start) {
			memcpy(pid_info_img->path, path_start, path_size);
		}
		ret = 0;
	} else {
		ret = -ENOMEM;
	}

	mem_free(path_buf);
out:
	return ret;
}

int fs_root_return_msg_new(msg_varsized_t *msg, pid_t nr)
{
	int ret;

	struct pid *pid;
	struct task_struct *task;
	struct path target_fs_root;
	struct path current_fs_root;

	char *path_buf = NULL;
	const char *path_start = NULL;

	size_t path_size;
	size_t fs_root_img_size;
	msg_sized_t *smsg;
	size_t msg_img_size;

	msg_img_t *msg_img;
	fs_root_img_t *fs_root_img;

	pid = find_get_pid(nr);
	task = get_pid_task(pid, PIDTYPE_PID);
	put_pid(pid);

	if (!task) {
		WPRINTF("'%s(%i)' failure", "get_pid_task", nr);
		return -ENOENT;
	}
	if (!task->fs) {
		WPRINTF("'task' %i without 'file system'", nr);
		put_task_struct(task);
		return -ENOENT;
	}
	get_fs_root(task->fs, &target_fs_root);
	put_task_struct(task);

	/*
	 * It is required that 'active_protection' is not chrooted - so, our
	 * root is global root.
	 */
	get_fs_root(current->fs, &current_fs_root);
	// if (process is chroot'ed)
	if ((target_fs_root.dentry != current_fs_root.dentry) ||
	    (target_fs_root.mnt    != current_fs_root.mnt)) {
		ret = path_to_string(&path_buf, &path_start, &target_fs_root);
		if (ret) {
			WPRINTF("'%s' failure, err = %d", "path_to_string", ret);
			path_put(&target_fs_root);
			path_put(&current_fs_root);
			return ret;
		}
	}
	path_put(&target_fs_root);
	path_put(&current_fs_root);

	path_size = path_start ? strlen(path_start) + 1 : 0;
	fs_root_img_size = sizeof(fs_root_img_t) + path_size;
	msg_img_size = sizeof(msg_img_t) + fs_root_img_size;

	smsg = msg_varsized_init_type(msg, msg_img_size, RT_FS_ROOT);
	if (!smsg) {
		mem_free(path_buf);
		return -ENOMEM;
	}

	msg_img = MSG_IMG(smsg);
	fs_root_img = IMG_PAYLOAD(msg_img);

	if (path_start)
		memcpy(fs_root_img->fs_root, path_start, path_size);

	mem_free(path_buf);

	return 0;
}

int open_file_return_msg_new(msg_varsized_t *msg, int fd)
{
	size_t msg_img_size;
	msg_img_t *msg_img;
	opened_file_img_t *open_file_img;
	msg_sized_t *smsg;

	msg_img_size = sizeof(msg_img_t) + sizeof(opened_file_img_t);
	smsg = msg_varsized_init_type(msg, msg_img_size, RT_OPENED_FILE);
	if (!smsg) {
		return -ENOMEM;
	}

	msg_img = MSG_IMG(smsg);
	open_file_img = IMG_PAYLOAD(msg_img);
	open_file_img->fd = fd;

	return 0;
}

int version_info_return_msg_new(msg_varsized_t *msg)
{
	size_t msg_img_size;
	msg_img_t *msg_img;
	version_info_img_t *version_info_img;
	msg_sized_t *smsg;

	msg_img_size = sizeof(msg_img_t) + sizeof(version_info_img_t);
	smsg = msg_varsized_init_type(msg, msg_img_size, RT_VERSION_INFO);
	if (!smsg) {
		return -ENOMEM;
	}

	msg_img = MSG_IMG(smsg);
	version_info_img = IMG_PAYLOAD(msg_img);
	version_info_img->max_action = AT_LAST;
	version_info_img->features = DRIVER_FEATURE_CLOSE_EVENT;

	return 0;
}

int data_queue_offsets_return_msg_new(msg_varsized_t *msg, uint32_t size)
{
	size_t msg_img_size;
	msg_img_t *msg_img;
	data_queue_offsets_t *data_queue_offsets_img;
	msg_sized_t *smsg;

	msg_img_size = sizeof(msg_img_t) + sizeof(data_queue_offsets_t);
	smsg = msg_varsized_init_type(msg, msg_img_size, RT_DATA_QUEUE_OFFSETS);
	if (!smsg) {
		return -ENOMEM;
	}

	msg_img = MSG_IMG(smsg);
	data_queue_offsets_img = IMG_PAYLOAD(msg_img);
	data_queue_offsets_img->size = size;
	data_queue_offsets_img->headOff = offsetof(shared_data_queue_t, head);
	data_queue_offsets_img->tailOff = offsetof(shared_data_queue_t, tail);
	data_queue_offsets_img->entriesOff = offsetof(shared_data_queue_t, entries);

	return 0;
}

// Checks pid's 'executable file' and sends 'exec' message in case of change.
// FIXME: move out of 'message.*'
void detect_exec(void)
{
	send_msg_sync_unref(heur_exec_msg_new());
}

Anon7 - 2021