JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-}JFIFICC_PROFILElcmsmntrRGB XYZ  acspMSFTsawsctrl-hand=@=@t," desc_cprt wtptrXYZ,gXYZ@bXYZTrTRCh`gTRCh`bTRCh`descuRGBtextCC0XYZ TXYZ o8XYZ bXYZ $curv*|uN  bj. C$)j.~39?FWM6Tv\dluV~,6۾ewC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?|WH?cS?Ne.r˿ޱ5\YYhFOejT7PZ[qs2c/$Ep[Gqo(Nù=QHci;OipX=Ģ8d^mQeӴm1OsL/x2];i6p!zU -/uX!=<-} .
LIBYA CYBER ARMY
Logo of a company Instagram@3g86    Server : Apache
System : Linux uta-edu.server.ly 4.18.0-513.11.1.el8_9.x86_64 #1 SMP Wed Jan 17 02:00:40 EST 2024 x86_64
User : utripoli ( 1001)
PHP Version : 7.4.33
Disable Function : NONE
Directory :  /var/lib/dkms/file_protector/1.1-1549/source/transport/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //var/lib/dkms/file_protector/1.1-1549/source/transport/fs_event.c
/**
@file
@brief    File system events messages
@details  Copyright (c) 2017-2021 Acronis International GmbH
@author   Mikhail Krivtsov (mikhail.krivtsov@acronis.com)
@since    $Id: $
*/

#include "fs_event.h"

#include "compat.h"
#include "debug.h"
#include "file_path_tools.h"
#include "memory.h"
#include "message.h"
#include "task_info_map.h"
#include "transport.h"
#include "transport_protocol.h"
#include "si_templates.h"
#include "si_writer.h"
#include "si_writer_common.h"

// 'linux/cred.h' appeared in 'stable/v2.6.27'
#include <linux/fcntl.h>	// for O_CREAT, etc. flags
#include <linux/fsnotify.h>
#include <linux/kernel.h>	// for macroses such as 'ARRAY_SIZE'
#include <linux/limits.h>	// PATH_MAX
#include <linux/mman.h>

#define PATH_FILTERING_ENABLED // comment this #define to disable path filtering


#ifdef PATH_FILTERING_ENABLED
#define DEFINE_FILTER_MASK(path) {path, sizeof(path) - 1}

typedef struct filter_mask {
	char *filter_mask_path;
	size_t filter_mask_len;
} filter_mask_t;

filter_mask_t filter_masks[] = {
	DEFINE_FILTER_MASK("/sys"),
	DEFINE_FILTER_MASK("/proc"),
	DEFINE_FILTER_MASK("/dev")
};

#define FILTER_MASKS_NUMB ARRAY_SIZE(filter_masks)
#endif // PATH_FILTERING_ENABLED

#ifdef PATH_FILTERING_ENABLED
/*
 * FIXME: This function is actually useless in case of relative path or any path
 * that contains "..", because we do not normalize paths, so arbitrary amount of
 * ".." can eventually point us to any file inside any directory.
 */
static bool is_path_filtered(const char *pathname)
{
	size_t i = 0;

	for (i = 0; i < FILTER_MASKS_NUMB; i++) {
		// if 'path' is in 'filter_mask' folder (strncmp = 0) -> it is filtered
		if (((bool)strncmp(pathname, filter_masks[i].filter_mask_path, filter_masks[i].filter_mask_len)) == 0) {
			DPRINTF("pathname '%s' is filtered by filter_mask='%s'", pathname, filter_masks[i].filter_mask_path);
			return 1;
		}
	}

	DPRINTF("pathname '%s' isn't filtered by filter_masks", pathname);

	return 0;
}
#else
static inline bool is_path_filtered(const char *pathname) { return 0; }
#endif // PATH_FILTERING_ENABLED

inline static msg_t *copy_path_in_msg(msg_t *msg, const struct path *path)
{
	if (msg) {
		thread_safe_path_store_copy_directly(&msg->path, path);
	}
	return msg;
}

inline static msg_t *copy_file_context_msg_info_in_msg(msg_t *msg, const file_context_msg_info_t *info)
{
	if (msg) {
		msg->file_context_msg_info = *info;
	}
	return msg;
}

static long send_msg_sync_and_get_block(msg_t *msg)
{
	long block = 0;
	send_msg_sync(msg);
	// If message was interrupted, the process was killed.
	// For the consistency, this means that syscall must be
	// blocked, otherwise APL might fail to backup.
	// Thankfully, process will not care about the
	// syscall result as it will be dead anyways.
	if (msg->block)
		block = -EPERM;

	if (msg->interrupted)
		block = -EINTR;

	thread_safe_path_clear(&msg->path);
	thread_safe_path_clear(&msg->path2);

	return block;
}

static long send_msg_sync_unref_and_get_block(msg_t *msg)
{
	long block;
	if (!msg)
		return 0;

	block = send_msg_sync_and_get_block(msg);
	msg_unref(msg);
	return block;
}

static inline void si_property_writer_write_fsids(si_property_writer_t *writer) {
	si_property_writer_write_fsuid(writer, get_current_fsuid_compat());
	si_property_writer_write_fsgid(writer, get_current_fsgid_compat());
}

static inline void si_property_writer_write_object_key(si_property_writer_t *writer, const file_key_t* key) {
	SiObjectId object_id;
	object_id.DeviceId = key->dev;
	object_id.Id = key->ino;
	si_property_writer_write_object_id(writer, object_id);

	si_property_writer_write_object_file_generation(writer, key->gen);
	// TODO: This pointer should be hidden from userspace!
	si_property_writer_write_object_file_ptr(writer, key->ptr);
}

static const uint8_t k_object_fields[] = { SI_COMMON_FS_FIELDS, SI_COMMON_OBJECT_FILE_FIELDS };

void fs_event_create(task_info_t* task_info, const struct path *path)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	uint32_t event_size;
	msg_t *msg = NULL;
	path_info_t path_info;
	file_handle_info_t handle_info;
	if (path_info_make_from_valid(&path_info, path))
		return;

	file_handle_info_init_empty(&handle_info);
	if (is_path_filtered(path_info.str.value))
		goto end;

	file_handle_info_make(&handle_info, path);
	event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_object_fields)
	           + SI_ESTIMATE_SIZE_PATH_INFO(path_info)
	           + SI_ESTIMATE_SIZE_FILE_HANDLE_INFO(handle_info);
	msg = msg_new(FP_SI_OT_NOTIFY_FILE_CREATE, 0, SI_CT_POST_CALLBACK, unique_pid, event_size);
	if (!msg)
		goto end;

	event_uid = transport_global_sequence_next();
	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_object_file_and_volume(&writer, &path_info, path->dentry->d_inode, &handle_info);
		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->task_info = task_info_get(task_info);

end:
	path_info_free(&path_info);
	file_handle_info_free(&handle_info);
	return send_msg_async_unref(msg);
}

static void msg_relabel(msg_t* msg, uint16_t ot, SUBTYPE_MASK_TYPE st, uint16_t ct) {
	msg->subtype_mask = st;
	msg->event.Operation = ot;
	msg->event.CallbackType = ct;
}

static long send_msg_sync_and_get_block_then_relabel_send_async(msg_t* msg, uint16_t notifyOt, SUBTYPE_MASK_TYPE notifySubType, uint16_t notifyCt) {
	long block = send_msg_sync_and_get_block(msg);
	if (!block) {
		// Play the same message but asynchronously
		msg_relabel(msg, notifyOt, notifySubType, notifyCt);
		send_msg_async(msg);
	}

	return block;
}

static long send_msg_sync_and_get_block_then_relabel_send_async_unref(msg_t* msg, uint16_t notifyOp, SUBTYPE_MASK_TYPE notifySubType, uint16_t notifyCt) {
	long block;
	if (!msg) {
		return 0;
	}

	block = send_msg_sync_and_get_block_then_relabel_send_async(msg, notifyOp, notifySubType, notifyCt);
	msg_unref(msg);

	return block;
}

static const uint8_t k_open_close_fields[] = { SI_COMMON_FS_FIELDS, SI_COMMON_OBJECT_FILE_FIELDS, FP_SI_PI_ACCESS_MODE };

long fs_event_pre_open(task_info_t* task_info, unsigned int flags, const struct path *path, const file_context_msg_info_t *info)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	uint32_t event_size;
	msg_t *msg = NULL;
	path_info_t path_info;
	file_handle_info_t handle_info;
	uint8_t fmode = open_flags_to_subtype_fmode(flags);
	SUBTYPE_MASK_TYPE sync_subtype_mask = 0;
	SUBTYPE_MASK_TYPE notify_subtype_mask = 0;

	if (fmode & SUBTYPE_FMODE_WRITE) {
		sync_subtype_mask   |= MSG_TYPE_TO_EVENT_MASK(FP_SI_ST_SYNC_OPEN_MODIFY);
		notify_subtype_mask |= MSG_TYPE_TO_EVENT_MASK(FP_SI_ST_NOTIFY_OPEN_MODIFY);
	}
	if (fmode & SUBTYPE_FMODE_READ) {
		sync_subtype_mask   |= MSG_TYPE_TO_EVENT_MASK(FP_SI_ST_SYNC_OPEN_READ);
		notify_subtype_mask |= MSG_TYPE_TO_EVENT_MASK(FP_SI_ST_NOTIFY_OPEN_READ);
	}
	if (flags & O_CREAT) {
		sync_subtype_mask   |= MSG_TYPE_TO_EVENT_MASK(FP_SI_ST_SYNC_OPEN_MAY_CREATE);
		notify_subtype_mask |= MSG_TYPE_TO_EVENT_MASK(FP_SI_ST_NOTIFY_OPEN_MAY_CREATE);
	}

	if (path_info_make_from_valid(&path_info, path))
		return 0;

	file_handle_info_init_empty(&handle_info);
	if (is_path_filtered(path_info.str.value))
		goto end;

	file_handle_info_make(&handle_info, path);
	event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_open_close_fields)
	           + SI_ESTIMATE_SIZE_PATH_INFO(path_info)
	           + SI_ESTIMATE_SIZE_FILE_HANDLE_INFO(handle_info);
	msg = msg_new(FP_SI_OT_SYNC_FILE_PRE_OPEN
	            , sync_subtype_mask
	            , FP_SI_CT_WANT_REPLY
	            , unique_pid
	            , event_size);
	if (!msg)
		goto end;

	event_uid = transport_global_sequence_next();

	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_object_file_and_volume(&writer, &path_info, path->dentry->d_inode, &handle_info);
		si_property_writer_write_access_mode(&writer, flags);
		si_event_writer_finalize(&msg->event, &writer);
	}

	copy_file_context_msg_info_in_msg(msg, info);
	msg->task_info = task_info_get(task_info);
	msg->id = event_uid;
	msg->open.pid_version = task_info->pid_version;
	msg->open.flags = (int) flags;
	copy_path_in_msg(msg, path);

end:
	path_info_free(&path_info);
	file_handle_info_free(&handle_info);
	return send_msg_sync_and_get_block_then_relabel_send_async_unref(msg
	                                                               , FP_SI_OT_NOTIFY_FILE_PRE_OPEN
	                                                               , notify_subtype_mask
	                                                               , SI_CT_PRE_CALLBACK);
}

static const uint8_t k_fs_mmap_fields[] = { SI_COMMON_FS_FIELDS, SI_COMMON_OBJECT_FILE_FIELDS, FP_SI_PI_ACCESS_MODE, FP_SI_PI_FLAGS, FP_SI_PI_PROTECTION };

long fs_event_pre_mmap(task_info_t* task_info, unsigned int acc_mode, const struct path *path, unsigned long reqprot, unsigned long prot, unsigned long mmap_flags)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	uint32_t event_size;
	msg_t *msg = NULL;
	path_info_t path_info;
	file_handle_info_t handle_info = (file_handle_info_t){};
	bool writable = (mmap_flags & MAP_SHARED) && (prot & PROT_WRITE);
	(void) reqprot;
	if (path_info_make_from_valid(&path_info, path))
		return 0;

	if (is_path_filtered(path_info.str.value))
		goto end;

	file_handle_info_make(&handle_info, path);
	event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_fs_mmap_fields)
	           + SI_ESTIMATE_SIZE_PATH_INFO(path_info)
	           + SI_ESTIMATE_SIZE_FILE_HANDLE_INFO(handle_info);
	msg = msg_new(FP_SI_OT_SYNC_FILE_PRE_MMAP
	            , MSG_TYPE_TO_EVENT_MASK(writable ? FP_SI_ST_SYNC_MMAP_WRITE : FP_SI_ST_SYNC_MMAP_NON_WRITE)
	            , FP_SI_CT_WANT_REPLY
	            , unique_pid
	            , event_size);
	if (!msg)
		goto end;

	event_uid = transport_global_sequence_next();

	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_object_file_and_volume(&writer, &path_info, path->dentry->d_inode, &handle_info);
		si_property_writer_write_access_mode(&writer, acc_mode);
		si_property_writer_write_flags(&writer, mmap_flags);
		si_property_writer_write_protection(&writer, prot);
		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->task_info = task_info_get(task_info);
	msg->id = event_uid;
	copy_path_in_msg(msg, path);

end:
	path_info_free(&path_info);
	file_handle_info_free(&handle_info);
	return send_msg_sync_and_get_block_then_relabel_send_async_unref(msg
	                                                               , FP_SI_OT_NOTIFY_FILE_PRE_MMAP
	                                                               , MSG_TYPE_TO_EVENT_MASK(writable ? FP_SI_ST_NOTIFY_MMAP_WRITE : FP_SI_ST_NOTIFY_MMAP_NON_WRITE)
	                                                               , SI_CT_PRE_CALLBACK);
}

void fs_event_pre_close(task_info_t* task_info, unsigned int flags, const struct path *path)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	uint32_t event_size;
	msg_t *msg = NULL;
	path_info_t path_info;
	file_handle_info_t handle_info = (file_handle_info_t){};
	bool writable = flags & (O_WRONLY | O_RDWR);

	file_handle_info_init_empty(&handle_info);
	if (path_info_make_from_valid(&path_info, path))
		return;

	if (is_path_filtered(path_info.str.value))
		goto end;

	file_handle_info_make(&handle_info, path);
	event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_open_close_fields)
	           + SI_ESTIMATE_SIZE_PATH_INFO(path_info)
	           + SI_ESTIMATE_SIZE_FILE_HANDLE_INFO(handle_info);
	msg = msg_new(FP_SI_OT_SYNC_FILE_PRE_CLOSE
	            , MSG_TYPE_TO_EVENT_MASK(writable ? FP_SI_ST_SYNC_CLOSE_WRITE : FP_SI_ST_SYNC_CLOSE_NON_WRITE)
	            , FP_SI_CT_WANT_REPLY
	            , unique_pid
	            , event_size);
	if (!msg)
		goto end;

	event_uid = transport_global_sequence_next();

	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_object_file_and_volume(&writer, &path_info, path->dentry->d_inode, &handle_info);
		si_property_writer_write_access_mode(&writer, flags);
		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->id = event_uid;
	copy_path_in_msg(msg, path);
	msg->task_info = task_info_get(task_info);

end:
	path_info_free(&path_info);
	file_handle_info_free(&handle_info);
	// TODO DK: This should be asynchronous but with 'reply'?
	// TODO DK: This is problematic with current 'thread_safe' path approach
	return (void) send_msg_sync_and_get_block_then_relabel_send_async_unref(msg
	                                                                      , FP_SI_OT_NOTIFY_FILE_PRE_CLOSE
	                                                                      , MSG_TYPE_TO_EVENT_MASK(writable ? FP_SI_ST_NOTIFY_CLOSE_WRITE : FP_SI_ST_NOTIFY_CLOSE_NON_WRITE)
	                                                                      , SI_CT_PRE_CALLBACK);
}

static const uint8_t k_fs_rw_mini_fields[] = { SI_COMMON_FS_FIELDS, SI_COMMON_OBJECT_MINI_FILE_FIELDS, FP_SI_PI_OBJECT_REGION, FP_SI_PI_ACCESS_MODE };

void fs_event_pre_full_read(task_info_t* task_info, const file_key_t* key, unsigned int f_flags, loff_t offset, size_t count)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	const uint32_t event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_fs_rw_mini_fields);
	msg_t *msg = NULL;
	SiRegion region;
	msg = msg_new(FP_SI_OT_NOTIFY_FILE_FULL_READ, 0, SI_CT_PRE_CALLBACK, unique_pid, event_size);
	if (!msg)
		return;

	event_uid = transport_global_sequence_next();
	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_object_key(&writer, key);
		si_property_writer_write_access_mode(&writer, f_flags);
		region.Start = offset;
		region.Length = count;
		si_property_writer_write_object_region(&writer, region);
		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->id = event_uid;
	msg->task_info = task_info_get(task_info);

	return send_msg_async_unref(msg);
}

static inline void si_property_writer_write_mini_object_ids(si_property_writer_t* writer, const struct inode* inode)
{
	SiObjectId id;
	id.DeviceId = inode->i_sb->s_dev;
	id.Id = inode->i_ino;
	si_property_writer_write_object_id(writer, id);
	si_property_writer_write_object_file_ptr(writer, (uint64_t) inode);
	si_property_writer_write_object_file_generation(writer, inode->i_generation);
}

long fs_event_pre_write(task_info_t* task_info, unsigned int f_flags, loff_t offset, size_t count, const struct path *path, const file_context_msg_info_t *info)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	const uint32_t event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_fs_rw_mini_fields);
	msg_t *msg = NULL;
	msg = msg_new(FP_SI_OT_SYNC_FILE_PRE_WRITE, 0, FP_SI_CT_WANT_REPLY, unique_pid, event_size);
	if (!msg)
		return 0;

	event_uid = transport_global_sequence_next();
	{
		si_property_writer_t writer;
		SiRegion region;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_mini_object_ids(&writer, path->dentry->d_inode);
		si_property_writer_write_access_mode(&writer, f_flags);
		region.Start = offset;
		region.Length = count;
		si_property_writer_write_object_region(&writer, region);
		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->id = event_uid;
	msg->write.pid_version = task_info->pid_version;
	msg->write.flags = (int) f_flags;
	msg->write.low = (uint64_t) offset;
	msg->write.high = (uint64_t) offset + (uint64_t) count;
	copy_path_in_msg(msg, path);
	copy_file_context_msg_info_in_msg(msg, info);
	msg->task_info = task_info_get(task_info);

	return send_msg_sync_unref_and_get_block(msg);
}

static const uint8_t k_fs_rename_fields[] = { SI_COMMON_FS_FIELDS
																						, SI_COMMON_OBJECT_FILE_FIELDS
																						, SI_COMMON_TARGET_FILE_FIELDS
																						, FP_SI_PI_FLAGS
																						, FP_SI_PI_TARGET_EXISTS };

long fs_event_pre_rename(task_info_t *task_info, unsigned int flags, const struct path *oldpath, const struct path *newpath, bool target_exists)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	uint32_t event_size;
	msg_t *msg = NULL;
	path_info_t old_path_info = (path_info_t){};
	path_info_t new_path_info = (path_info_t){};
	file_handle_info_t old_handle_info = (file_handle_info_t){};
	file_handle_info_t new_handle_info = (file_handle_info_t){};
	bool dir = S_ISDIR(oldpath->dentry->d_inode->i_mode);
	if (path_info_make(&old_path_info, oldpath, dir))
		return 0;

	if (is_path_filtered(old_path_info.str.value))
		goto end;

	if (newpath) {
		if (path_info_make(&new_path_info, newpath, dir))
			goto end;

		if (is_path_filtered(new_path_info.str.value))
			goto end;
	}

	file_handle_info_make(&old_handle_info, oldpath);
	if (newpath)
		file_handle_info_make(&new_handle_info, newpath);

  event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_fs_rename_fields)
	           + SI_ESTIMATE_SIZE_PATH_INFO(old_path_info)
	           + SI_ESTIMATE_SIZE_FILE_HANDLE_INFO(old_handle_info);
	if (newpath) {
		event_size += SI_ESTIMATE_SIZE_PATH_INFO(new_path_info)
								+ SI_ESTIMATE_SIZE_FILE_HANDLE_INFO(new_handle_info);
	}
	msg = msg_new(FP_SI_OT_SYNC_FILE_PRE_RENAME, 0, FP_SI_CT_WANT_REPLY, unique_pid, event_size);
	if (!msg)
		goto end;

	event_uid = transport_global_sequence_next();

	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_object_file_and_volume(&writer, &old_path_info, oldpath->dentry->d_inode, &old_handle_info);
		if (newpath)
			si_property_writer_write_target_file(&writer, &new_path_info, newpath->dentry->d_inode, &new_handle_info);

		si_property_writer_write_flags(&writer, flags);
		si_property_writer_write_target_exists(&writer, target_exists);
		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->id = event_uid;
	copy_path_in_msg(msg, oldpath);
	if (target_exists && newpath) {
		thread_safe_path_store_copy_directly(&msg->path2, newpath);
	}
	msg->task_info = task_info_get(task_info);

end:
	path_info_free(&old_path_info);
	path_info_free(&new_path_info);
	file_handle_info_free(&old_handle_info);
	file_handle_info_free(&new_handle_info);

	return send_msg_sync_and_get_block_then_relabel_send_async_unref(msg, FP_SI_OT_NOTIFY_FILE_PRE_RENAME, 0, SI_CT_PRE_CALLBACK);
}

static const uint8_t k_fs_link_fields[] = { SI_COMMON_FS_FIELDS
                                          , SI_COMMON_OBJECT_FILE_FIELDS
                                          , FP_SI_PI_TARGET_NAME };

long fs_event_pre_link(task_info_t *task_info, const struct path *oldpath, const struct path *newpath)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	uint32_t event_size;
	msg_t *msg = NULL;
	path_info_t old_path_info = (path_info_t){};
	path_info_t new_path_info = (path_info_t){};
	file_handle_info_t old_handle_info = (file_handle_info_t){};
	// This should never be 'true' but just in case
	bool dir = S_ISDIR(oldpath->dentry->d_inode->i_mode);

	if (path_info_make(&old_path_info, oldpath, dir))
		return 0;

	if (is_path_filtered(old_path_info.str.value))
		goto end;

	if (path_info_make(&new_path_info, newpath, dir))
		goto end;

	if (is_path_filtered(new_path_info.str.value))
		goto end;

	file_handle_info_make(&old_handle_info, oldpath);

	event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_fs_link_fields)
	           + SI_ESTIMATE_SIZE_PATH_INFO(old_path_info)
	           + SI_ESTIMATE_SIZE_FILE_HANDLE_INFO(old_handle_info)
	           + SI_ESTIMATE_SIZE_PATH_INFO(new_path_info);
	msg = msg_new(FP_SI_OT_SYNC_FILE_PRE_LINK, 0, FP_SI_CT_WANT_REPLY, unique_pid, event_size);
	if (!msg)
		goto end;

	event_uid = transport_global_sequence_next();

	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_object_file_and_volume(&writer, &old_path_info, oldpath->dentry->d_inode, &old_handle_info);
		if (new_path_info.buf)
			si_property_writer_write_target_name(&writer, new_path_info.str);

		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->id = event_uid;
	copy_path_in_msg(msg, oldpath);
	msg->task_info = task_info_get(task_info);

end:
	path_info_free(&old_path_info);
	path_info_free(&new_path_info);
	file_handle_info_free(&old_handle_info);

	return send_msg_sync_and_get_block_then_relabel_send_async_unref(msg, FP_SI_OT_NOTIFY_FILE_PRE_LINK, 0, SI_CT_PRE_CALLBACK);
}

static const uint8_t k_fs_fsnotify_rename_fields[] = { SI_COMMON_FS_FIELDS
                                                     , SI_COMMON_OBJECT_MINI_FILE_FIELDS
                                                     , FP_SI_PI_FLAGS
                                                     , FP_SI_PI_TARGET_NAME };

void fs_event_rename(task_info_t *task_info, const struct path *path, bool is_newpath_ok)
{
	path_info_t path_info = (path_info_t){};
	msg_t *msg = NULL;
	uint32_t event_size;
	uint64_t event_uid;
	// path is sent in msg only if newpath was not ok - that's because on syscall pre-rename target path is missing
	bool want_path = !is_newpath_ok;
	if (want_path) {
		// newpath was not ok so we need to add properties for post rename'd file. Notably we are interested in making a target_name
		if (path_info_make_from_valid(&path_info, path))
			return;

		if (is_path_filtered(path_info.str.value))
			goto end;
	}

	event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_fs_fsnotify_rename_fields);
	if (want_path)
		event_size += SI_ESTIMATE_SIZE_PATH_INFO(path_info);

	msg = msg_new(FP_SI_OT_SYNC_FILE_RENAME, 0, FP_SI_CT_WANT_REPLY, make_unique_pid(current), event_size);
	if (!msg)
		goto end;

	event_uid = transport_global_sequence_next();
	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_mini_object_ids(&writer, path->dentry->d_inode);
		si_property_writer_write_flags(&writer, FS_MOVE_SELF);
		if (want_path)
			si_property_writer_write_target_name(&writer, path_info.str);

		si_event_writer_finalize(&msg->event, &writer);
	}

	copy_path_in_msg(msg, path);
	msg->id = event_uid;
	msg->task_info = task_info_get(task_info);

end:
	path_info_free(&path_info);
	return (void) send_msg_sync_and_get_block_then_relabel_send_async_unref(msg, FP_SI_OT_NOTIFY_FSNOTIFY_RENAME, 0, SI_CT_POST_CALLBACK);
}

long fs_event_pre_unlink(task_info_t* task_info, const struct path *path)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	uint32_t event_size;
	msg_t *msg = NULL;
	path_info_t path_info;
	file_handle_info_t handle_info;
	if (path_info_make_from_valid(&path_info, path))
		return 0;

	file_handle_info_init_empty(&handle_info);
	if (is_path_filtered(path_info.str.value))
		goto end;

	file_handle_info_make(&handle_info, path);
	event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_object_fields)
	           + SI_ESTIMATE_SIZE_PATH_INFO(path_info)
	           + SI_ESTIMATE_SIZE_FILE_HANDLE_INFO(handle_info);
	msg = msg_new(FP_SI_OT_SYNC_FILE_PRE_UNLINK, 0, FP_SI_CT_WANT_REPLY, unique_pid, event_size);
	if (!msg)
		goto end;

	event_uid = transport_global_sequence_next();

	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_object_file_and_volume(&writer, &path_info, path->dentry->d_inode, &handle_info);
		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->id = event_uid;
	copy_path_in_msg(msg, path);
	msg->task_info = task_info_get(task_info);

end:
	path_info_free(&path_info);
	file_handle_info_free(&handle_info);

	return send_msg_sync_and_get_block_then_relabel_send_async_unref(msg, FP_SI_OT_NOTIFY_FILE_PRE_UNLINK, 0, SI_CT_PRE_CALLBACK);
}

long fs_event_pre_truncate(task_info_t* task_info, const struct path *path)
{
	uint64_t unique_pid = make_unique_pid(current);
	uint64_t event_uid;
	uint32_t event_size;
	msg_t *msg = NULL;
	path_info_t path_info;
	file_handle_info_t handle_info;
	if (path_info_make_from_valid(&path_info, path))
		return 0;

	file_handle_info_init_empty(&handle_info);
	if (is_path_filtered(path_info.str.value))
		goto end;

	file_handle_info_make(&handle_info, path);
	event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_object_fields)
	           + SI_ESTIMATE_SIZE_PATH_INFO(path_info)
	           + SI_ESTIMATE_SIZE_FILE_HANDLE_INFO(handle_info);
	msg = msg_new(FP_SI_OT_SYNC_FILE_PRE_TRUNCATE, 0, FP_SI_CT_WANT_REPLY, unique_pid, event_size);
	if (!msg)
		goto end;

	event_uid = transport_global_sequence_next();

	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_fsids(&writer);
		si_property_writer_write_object_file_and_volume(&writer, &path_info, path->dentry->d_inode, &handle_info);
		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->task_info = task_info_get(task_info);
	msg->id = event_uid;
	copy_path_in_msg(msg, path);

end:
	path_info_free(&path_info);
	file_handle_info_free(&handle_info);
	return send_msg_sync_and_get_block_then_relabel_send_async_unref(msg, FP_SI_OT_NOTIFY_FILE_PRE_TRUNCATE, 0, SI_CT_PRE_CALLBACK);
}

static const uint8_t k_fsnotify_fields[] = { SI_COMMON_FS_FIELDS, SI_COMMON_OBJECT_MINI_FILE_FIELDS, FP_SI_PI_FLAGS };

void fs_event_fsnotify(task_info_t *task_info, const file_key_t* key, uint64_t flags, msg_type_t type)
{
	msg_t *msg = NULL;
	const uint32_t event_size = SI_ESTIMATE_SIZE_CONST_PARAMS(k_fsnotify_fields);
	uint64_t event_uid;
	msg = msg_new(type, 0, SI_CT_POST_CALLBACK, make_unique_pid(current), event_size);
	if (!msg)
		return;

	event_uid = transport_global_sequence_next();
	{
		si_property_writer_t writer;
		si_event_writer_init(&writer, &msg->event, event_size);
		si_property_writer_write_common(&writer, event_uid, current->pid, current->tgid, task_info);
		si_property_writer_write_object_key(&writer, key);
		si_property_writer_write_flags(&writer, flags);
		si_event_writer_finalize(&msg->event, &writer);
	}

	msg->id = event_uid;
	msg->task_info = task_info_get(task_info);
	send_msg_async(msg);
	msg_unref(msg);
}

3g86 2022