shell bypass 403

Cubjrnet7 Shell


name : transport_protocol.h
/**
@file			transport_protocol.h
@brief    SI-based protocol
@details  Copyright (c) 2024 Acronis International GmbH
@author   Denis Kopyrin ([email protected])
@since    $Id: $
*/

#pragma once

// Note: This file is shared between kernel and user space transport code.

#ifndef BPF_PROGRAM
#define KERNEL_READ(p, m) ((p)->m)
#define KERNEL_READ2(p, m1, m2) ((p)->m1->m2)
// Note: Linux kernel build system defines '__KERNEL__'
#if defined __KERNEL__
#include <linux/types.h>	// bool, [u]int(8|16|32|64)_t, pid_t
#else
#include <stdbool.h>		// bool
#include <stdint.h>		// [u]int(8|16|32|64)_t
#include <sys/types.h>		// pid_t

#endif
#endif

#if !defined PACKED
#define PACKED __attribute__((packed))
#endif

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

#define TRANSPORT_DEVICE_NAME "apl_transport"

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

/*
    Each message is either a 'query' or a 'reply'. Each message contains
    an identifier ('id') necessary to match 'reply' to corresponding
    'query'. Zero 'id' in 'query' means that 'reply' is not necessary.
    'reply' with zero 'id' is not used.
*/

typedef uint64_t msg_id_t;

typedef enum {
	// reserved 0 as an error type
	AT_PING = 1,
	// 8 was reserved but now used for 'AT_GET_VERSION'
	// as it would behave fine - it was not used by ioctl or write
	AT_GET_VERSION = 8,

	AT_OPEN_FILE_FROM_MSG,
	AT_OPEN_FILE_BY_PATH,
	// 11 and 12 are reserved
	AT_INIT_SHARED_DATA_QUEUE = 13,
	AT_WAIT_SHARED_DATA_QUEUE,
	// 15 is reserved
	AT_FILE_CONTEXT_ADD = 16,

	AT_GET_MNT_ID_OFFSET,

	AT_SET_LISTENING_MASK_GLOBAL,
	AT_SET_LISTENING_MASK_PROCESS,

	AT_GET_PROCESS_INFO,
	AT_GET_PROCESS_PID_VERSION,

	// Provides mask of events that will be sent if subtype mask intersects
	// Default is all bits enabled.
	AT_SET_LISTENING_SUBTYPE_INCLUSION_MASK,
	// Providers mask of events that will be dropped if subtypes mask intersects.
	// Default is all bits disabled.
	AT_SET_LISTENING_SUBTYPE_EXCLUSION_MASK,

	AT_SET_TRANSPORT_CLIENT_TYPE,

	AT_LAST,
} action_type_t;

typedef enum {
	RT_ERROR = 0,
	// reserved till 8
	RT_OPENED_FILE = 9,
	RT_VERSION_INFO,
	RT_DATA_QUEUE_OFFSETS,
	RT_GET_MNT_ID_OFFSET,
	RT_GET_PROCESS_INFO,
	RT_GET_PROCESS_PID_VERSION,
} return_type_t;

typedef uint8_t msg_type_img_t;

typedef struct PACKED {
	msg_id_t id;
	msg_type_img_t type;	// msg_type_t
	bool reply;
	uint8_t payload[];
} request_msg_img_t;

inline static
msg_id_t msg_img_id(const request_msg_img_t *msg_img)
{
	return msg_img->id;
}

inline static
msg_type_img_t msg_img_type(const request_msg_img_t *msg_img)
{
	return msg_img->type;
}

inline static
bool msg_img_is_reply(const request_msg_img_t *msg_img)
{
	return msg_img->reply;
}

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

/*
    Generic 'reply' message
*/

// Note: Empty 'reply' may be used as shortcut for 'default' reply
/*
// Legacy 'reply_img_t'
typedef struct PACKED {
	uint8_t reply[];
} reply_img_t;
*/

typedef enum {
	RT_ALLOW,
	RT_BLOCK,
} reply_type_t;
typedef uint8_t reply_type_img_t;

typedef struct PACKED {
	reply_type_img_t type;
	uint8_t payload[];
} reply_img_t;

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

/*
    'transport' testing

    'pong' message is 'high level' reply to 'ping' message. 'pong'
    message returns 'payload' from 'ping' message.

    'ping' and 'pong' messages can be sent in both 'synchronous' (i.e
    with *_reply') and 'asynchronous' (i.e without *_reply') modes.

    'ping_reply' and 'pong_reply' are respective 'low level'
    confirmations for 'ping' and 'pong' messages. They do not return
    'payload'. Instead they return some arbitrary 'reply'.

		'ping' will set 'properties_number' and copy 'payload' as is, it is
		up to sender to interpret 'payload' correctly.
*/

typedef struct PACKED {
	uint64_t process_uid;
	uint32_t properties_number;
	uint8_t payload[];
} ping_img_t;

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

/*
    task_info_map management
*/

typedef uint32_t pid_img_t;
typedef uint32_t uid_img_t;
typedef uint32_t gid_img_t;

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

// AT_OPEN_FILE_FROM_MSG
typedef struct PACKED {
	// useful for 'rename*' message that may refer to 2 files
	int num;
} open_file_from_msg_img_t;

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

// AT_OPEN_FILE_BY_PATH
typedef struct PACKED {
	int flags;
	int mode;
	char path[];
} open_file_by_path_img_t;

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

// RT_OPENED_FILE
typedef struct PACKED {
	int fd;
} opened_file_img_t;

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

// AT_SET_LISTENING_MASK_PROCESS
typedef struct PACKED {
	pid_img_t pid;
	// You may provide pid_version==0 or unique_pid==0 to avoid checking those
	// but it is unlikely that it is what you actually need.
	// If unique_pid==0, a different process on pid wrapping might be filtered,
	// if pid_version==0, a different process exec instance might be filtered.
	uint64_t pid_version;
	uint64_t unique_pid;
	uint64_t events_mask;
} process_set_listening_mask_img_t;

// Complex events are events that are made from pre and post events together.
// It is very common that on LSM there is full information about the file path
// but on POST event there is only 'inode' which does not provide full path or mount.
// Userspace combines those 2 events to create a POST full event using 'replay cache'.

// Driver is capable of sending 'CLOSE' events
#define DRIVER_FEATURE_CLOSE_EVENT                     (1 << 0)

// Driver is using AUDIT events to generate Login/Logout events
#define DRIVER_FEATURE_AUDIT_EVENTS                    (1 << 1)

// Driver is using 'fsnotify' to send 'POST' events
#define DRIVER_FEATURE_FSNOTIFY_EVENTS                 (1 << 2)

// Driver is using LSM 'struct path' to instantiate OPEN events instead of syscall hooks
// This also means that driver is sending 'FSNOTIFY_CREATE' events for complex 'CREATE'.
// It is not explicitly specified how 'inode' 'CREATE' is done - it can be done via 'fsnotify' or LSM 'inode_create'.
// A usual flow is getting 'inode' CREATE event and enriching it with 'path' from LSM 'file_open' event.
// This flag requires 'DRIVER_FEATURE_FSNOTIFY_EVENTS' to be set.
#define DRIVER_FEATURE_LSM_FILE_OPEN_COMPLEX_CREATE    (1 << 3)

// Driver is using LSM with CONFIG_SECURITY_PATH to instantiate non-OPEN complex events
// instead of syscall hooks that are replayed using 'fsnotify' callbacks.
// There are currently 2 events that fall in this category - 'rename' and 'unlink/rmdir'.
// They needed to ensure those operations did succeed for POST callbacks.
// Userspace client is expected to handle PRE LSM events and verify it using POST 'fsnotify'.
// This flag requires 'DRIVER_FEATURE_FSNOTIFY_EVENTS' and 'DRIVER_FEATURE_LSM_GENERIC' to be set.
#define DRIVER_FEATURE_LSM_SECURITY_PATH_COMPLEX_POST  (1 << 4)

// Driver is leveraging proc_connector hooks to have sleepable process events.
// This allows to have a more stable process events and required from 'cmdline' in EXEC events.
#define DRIVER_FEATURE_SLEEPABLE_PROCESS_EVENTS        (1 << 5)

// Driver is using syscall hooks instead of LSM for events that requires complex POST.
// Such events are currently 'rename' and 'unlink/rmdir'.
// Should not be set with 'DRIVER_FEATURE_LSM_SECURITY_PATH_COMPLEX_POST'
#define DRIVER_FEATURE_FS_SYSCALL_HOOKS_COMPLEX_POST   (1 << 6)

// Driver is using LSM to generate generic events like 'settime' that do not require 'CONFIG_SECURITY_PATH'
#define DRIVER_FEATURE_LSM_GENERIC                     (1 << 7)

// Driver is using LSM with CONFIG_SECURITY_PATH to instantiate events that do not require 'fsnotify'
// For example those events are 'truncate', 'link',...
// This flag requires 'DRIVER_FEATURE_LSM_GENERIC' to be set.
#define DRIVER_FEATURE_LSM_SECURITY_PATH_SIMPLE_PRE    (1 << 8)

// Driver is providing 'mmap' events using LSM.
// This flag requires 'DRIVER_FEATURE_LSM_GENERIC' to be set.
#define DRIVER_FEATURE_LSM_FILE_MMAP                   (1 << 9)

// Driver can provide command line for EXEC events.
#define DRIVER_FEATURE_COMMAND_LINE_IN_EXEC            (1 << 10)

// Driver provides proper absolute paths in events without chroot
#define DRIVER_FEATURE_ABSOLUTE_PATHS                  (1 << 11)

// Driver is using 'rw_verify_area' to send read/write events
#define DRIVER_FEATURE_RW_VERIFY_AREA_EVENTS           (1 << 12)

// Driver is using LSM to send network events.
// This flag requires 'DRIVER_FEATURE_LSM_GENERIC' to be set.
#define DRIVER_FEATURE_LSM_NETWORK                     (1 << 13)

// Driver is capable of using kretprobe hooks
#define DRIVER_FEATURE_KRETPROBE_HOOKS                 (1 << 14)

// Driver can handle process failed lookups
#define DRIVER_FEATURE_FAILED_LOOKUP                   (1 << 15)

// Driver sends OS accelerated copy file events for 'sendfile'
#define DRIVER_FEATURE_COPYFILE_SPLICE                 (1 << 16)

// Driver sends OS accelerated copy file events for 'copy_file_range'
#define DRIVER_FEATURE_COPYFILE_COPY_FILE_RANGE        (1 << 17)

// Driver sends OS accelerated copy file events for 'FICLONE'
#define DRIVER_FEATURE_COPYFILE_CLONE                  (1 << 18)

// RT_VERSION_INFO
typedef struct PACKED {
	// Max Action allowed to be called in 'ioctl'/'write' calls
	// If AT_GET_VERSION errors out itself, 'max_action' should be AT_GET_VERSION
	uint8_t max_action;
	// Features exposed by the module that are outside of 'ioctl'/'write' scope
	uint64_t features;
} version_info_img_t;

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

#define MSG_TYPE_TO_EVENT_MASK(mt) (1ULL << (mt))

// AT_SET_LISTENING_MASK_GLOBAL
// AT_SET_LISTENING_SUBTYPE_INCLUSION_MASK
// AT_SET_LISTENING_SUBTYPE_EXCLUSION_MASK
typedef struct PACKED {
	// Mask of events as per 'LEGACY_MSG_TYPE_TO_EVENT_MASK' or per 'MSG_TYPE_TO_EVENT_MASK'
	uint64_t events_mask;
} events_mask_img_t;

typedef struct PACKED
{
	int mntId;
	int fd;
} mnt_info_t;

// AT_GET_MNT_ID_OFFSET
typedef struct PACKED {
	uint32_t count;
	char data[];
} mnt_info_img_t;

// RT_GET_MNT_ID_OFFSET
typedef struct PACKED {
	bool ok;
} mnt_info_ret_img_t;

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

typedef uint64_t offset_img_t;	// Note: 'loff_t' is 'signed'
typedef uint64_t size_img_t;

// Technically 'file_key_t' is not used in transport but it is oftentimes represented the same way
// in userspace and kernel space. So it is defined here for convenience.
typedef struct
{
  uint64_t ptr;
  uint64_t ino;
  uint64_t gen;
  uint64_t dev;
} file_key_t;

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

typedef enum {
	IOCTL_READ_MSG = 1,
	IOCTL_WRITE_MSG = 2,
	IOCTL_WRITE_AND_READ_MSG = 3,
	IOCTL_READ_VERSION = 4,
} ioctl_cmd_t;

typedef uint16_t ioctl_size_img_t;

typedef struct PACKED {
	ioctl_size_img_t capacity; // payload capacity;
	ioctl_size_img_t size; // actual payload size;
	uint8_t payload[];
} ioctl_hdr_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Shared Data queue protocol

// Entry description in the mmap'd buffer
// !!! This structure should be exactly the same as 'SiEvent' start !!!
typedef struct {
	uint32_t size;
	uint8_t data[];
} data_queue_entry_t;

// Params passed to the data_queue init
// AT_INIT_SHARED_DATA_QUEUE
typedef struct PACKED {
	uint32_t size;
} data_queue_params_t;

// Those offsets correspond to values in the 'mmap' buffer
//
/*
struct shared_data_queue {
	uint32_t size ____cacheline_aligned_in_smp;
	uint32_t head ____cacheline_aligned_in_smp;
	uint32_t tail ____cacheline_aligned_in_smp;
	struct data_queue_entry entries[] ____cacheline_aligned_in_smp;
};
*/
// RT_DATA_QUEUE_OFFSETS
typedef struct {
	uint32_t size; // as size of the whole 'queue'
	uint32_t headOff;
	uint32_t tailOff;
	uint32_t entriesOff;
} data_queue_offsets_t;

typedef struct PACKED {
	pid_img_t pid;		// pid_t
} get_pid_info_img_t;

typedef get_pid_info_img_t get_process_info_img_t;
typedef get_pid_info_img_t get_process_pid_version_img_t;

// RT_GET_PROCESS_PID_VERSION
// Returns 'generated' fields for the process from task info map
typedef struct PACKED {
	uint64_t pid_version;
	uint64_t artificial_process_start_timestamp;
} process_pid_version_ret_img_t;

// AT_SET_TRANSPORT_CLIENT_TYPE
typedef enum
{
  CLIENT_UNKNOWN,
  CLIENT_TEST,
  CLIENT_AP,
  CLIENT_RTP,
  CLIENT_BE,
} client_type_t;

#define TRANSPORT_MAX_NAME_LEN 16
typedef struct PACKED {
	uint8_t client_type; // client_type_t
} transport_client_type_img_t;

// New events are like SiEvent
// Will need to be 'recoded' to public SiEvent if necessary
typedef enum {
#define FP_SI_MSG_TYPE(x) FP_SI_OT_##x,
	#include "transport_message_types_x.h"
#undef FP_SI_MSG_TYPE
} msg_type_t;

typedef enum {
	// open is opening file to modify it. Usually it is WRITE but it can be O_TRUNC as well
	FP_SI_ST_SYNC_OPEN_MODIFY,
	// open has read permission
	// event will be risen only if either 'MODIFY' or 'OPEN' is on, O_PATH case is not sent
	FP_SI_ST_SYNC_OPEN_READ,
	// O_CREAT is on
	FP_SI_ST_SYNC_OPEN_MAY_CREATE,
	FP_SI_ST_NOTIFY_OPEN_MODIFY,
	FP_SI_ST_NOTIFY_OPEN_READ,
	FP_SI_ST_NOTIFY_OPEN_MAY_CREATE,

	// fsnotify only provides enough if file was opened with WRITE permissions so
	// the best distinguising factor here is WRITE or !WRITE
	FP_SI_ST_SYNC_CLOSE_WRITE,
	FP_SI_ST_SYNC_CLOSE_NON_WRITE,
	FP_SI_ST_NOTIFY_CLOSE_WRITE,
	FP_SI_ST_NOTIFY_CLOSE_NON_WRITE,

	// mmap WRITE is set only when mapping can writeback data to file
	FP_SI_ST_SYNC_MMAP_WRITE,
	FP_SI_ST_SYNC_MMAP_NON_WRITE,
	FP_SI_ST_NOTIFY_MMAP_WRITE,
	FP_SI_ST_NOTIFY_MMAP_NON_WRITE,

	// open is related to 'opendir' call
	FP_SI_ST_NOTIFY_OPENDIR,
	FP_SI_ST_SYNC_OPENDIR,

	// close is related to 'closedir' call
	FP_SI_ST_NOTIFY_CLOSEDIR,
	FP_SI_ST_SYNC_CLOSEDIR,

	// flag that is set for all 'special' files operations - !regular && !dir
	FP_SI_ST_SPECIAL,

	FP_SI_ST_COUNT,
} msg_subtype_t;

typedef enum {
	SI_PI_PRIVATE_PROPERTY_START = 0x4000,
	SI_PI_PRIVATE_FSUID,
	SI_PI_PRIVATE_FSGID,
	SI_PI_PRIVATE_PARENT_THREAD_ID,
	SI_PI_PRIVATE_OBJECT_FILE_GENERATION,
	SI_PI_PRIVATE_TARGET_FILE_GENERATION,
	SI_PI_PRIVATE_OBJECT_FILE_PTR,
	SI_PI_PRIVATE_TARGET_FILE_PTR,
	SI_PI_PRIVATE_OBJECT_FILE_MOUNT_ID,
	SI_PI_PRIVATE_TARGET_FILE_MOUNT_ID,
	SI_PI_PRIVATE_SEQUENCE_NUMBER,
	SI_PI_PRIVATE_TARGET_FILE_HANDLE,
	SI_PI_PRIVATE_TARGET_EXISTS,
	SI_PI_PRIVATE_OTHER_THREAD_ID,
	SI_PI_PRIVATE_OTHER_PROCESS_ID,
	SI_PI_PRIVATE_OTHER_PROCESS_ID_VERSION,
	SI_PI_PRIVATE_PARENT_PROCESS_ID_VERSION,
	SI_PI_PRIVATE_OTHER_ARTIFICIAL_PROCESS_START_TIMESTAMP,
	SI_PI_PRIVATE_FILE_MODE,
	SI_PI_PRIVATE_FILE_SIZE,
	SI_PI_PRIVATE_FILE_UID,
	SI_PI_PRIVATE_FILE_GID,
	SI_PI_PRIVATE_TARGET_FILE_ATTRIBUTES,
	SI_PI_PRIVATE_TARGET_FILE_MODE,
	SI_PI_PRIVATE_TARGET_FILE_SIZE,
	SI_PI_PRIVATE_TARGET_FILE_UID,
	SI_PI_PRIVATE_TARGET_FILE_GID,
	SI_PI_PRIVATE_TARGET_FILE_MODIFICATION_TIME,
	SI_PI_PRIVATE_TARGET_FILE_CHANGE_TIME,
	SI_PI_PRIVATE_TARGET_FILE_ACCESS_TIME,
	SI_PI_PRIVATE_VOLUME_MAGIC,
	SI_PI_PRIVATE_COMMAND_LINE_TRUNCATED,
	SI_PI_PRIVATE_OTHER_PROCESS_START_TIMESTAMP,
	SI_PI_PRIVATE_TARGET_FILE_BIRTH_TIME,
	SI_PI_PRIVATE_SOCKET_ADDRESS_IP,
	SI_PI_PRIVATE_LOG_STR,
	SI_PI_PRIVATE_SOCKET_LOCAL_ADDRESS_IP,
	SI_PI_PRIVATE_OBJECT_FILE_DENTRY_PTR,
	SI_PI_PRIVATE_OBJECT_FILE_DENTRY_NAME_PTR,

	FP_SI_PI_MAX_PRIVATE_PROPERTY_ID,
} si_private_property_id_t;

#define FP_SI_CT_WANT_REPLY 0xffff

© 2025 Cubjrnet7