Driver: fortconf: Refactor FORT_APP_ENTRY

This commit is contained in:
Nodir Temirkhodjaev 2024-03-28 20:07:57 +03:00
parent 85aeb4f064
commit b39ed544b0
12 changed files with 95 additions and 84 deletions

View File

@ -14,7 +14,7 @@ static_assert(sizeof(FORT_TRAF) == sizeof(UINT64), "FORT_TRAF size mismatch");
static_assert(sizeof(FORT_TIME) == sizeof(UINT16), "FORT_TIME size mismatch");
static_assert(sizeof(FORT_PERIOD) == sizeof(UINT32), "FORT_PERIOD size mismatch");
static_assert(sizeof(FORT_APP_FLAGS) == sizeof(UINT16), "FORT_APP_FLAGS size mismatch");
static_assert(sizeof(FORT_APP_ENTRY) == 2 * sizeof(UINT32), "FORT_APP_ENTRY size mismatch");
static_assert(sizeof(FORT_APP_DATA) == 2 * sizeof(UINT32), "FORT_APP_DATA size mismatch");
#ifndef FORT_DRIVER
# define fort_memcmp memcmp
@ -180,13 +180,10 @@ FORT_API BOOL fort_conf_ip_included(const PFORT_CONF conf,
FORT_API BOOL fort_conf_app_exe_equal(
const PFORT_APP_ENTRY app_entry, const PVOID path, UINT32 path_len)
{
const PVOID app_path = app_entry + 1;
const UINT32 app_path_len = app_entry->path_len;
if (path_len != app_path_len)
if (path_len != app_entry->path_len)
return FALSE;
return fort_memcmp(path, app_path, path_len) == 0;
return fort_memcmp(path, app_entry->path, path_len) == 0;
}
static BOOL fort_conf_app_wild_equal(
@ -194,18 +191,16 @@ static BOOL fort_conf_app_wild_equal(
{
UNUSED(path_len);
const WCHAR *app_path = (const WCHAR *) (app_entry + 1);
return wildmatch(app_path, (const WCHAR *) path) == WM_MATCH;
return wildmatch(app_entry->path, (const WCHAR *) path) == WM_MATCH;
}
typedef BOOL fort_conf_app_equal_func(
const PFORT_APP_ENTRY app_entry, const PVOID path, UINT32 path_len);
static FORT_APP_ENTRY fort_conf_app_find_loop(const PFORT_CONF conf, const PVOID path,
static FORT_APP_DATA fort_conf_app_find_loop(const PFORT_CONF conf, const PVOID path,
UINT32 path_len, UINT32 apps_off, UINT16 apps_n, fort_conf_app_equal_func *app_equal_func)
{
const FORT_APP_ENTRY app_data = { 0 };
const FORT_APP_DATA app_data = { 0 };
if (apps_n == 0)
return app_data;
@ -216,7 +211,7 @@ static FORT_APP_ENTRY fort_conf_app_find_loop(const PFORT_CONF conf, const PVOID
const PFORT_APP_ENTRY app_entry = (const PFORT_APP_ENTRY) app_entries;
if (app_equal_func(app_entry, path, path_len))
return *app_entry;
return app_entry->app_data;
app_entries += FORT_CONF_APP_ENTRY_SIZE(app_entry->path_len);
} while (--apps_n != 0);
@ -224,7 +219,7 @@ static FORT_APP_ENTRY fort_conf_app_find_loop(const PFORT_CONF conf, const PVOID
return app_data;
}
FORT_API FORT_APP_ENTRY fort_conf_app_exe_find(
FORT_API FORT_APP_DATA fort_conf_app_exe_find(
const PFORT_CONF conf, PVOID context, const PVOID path, UINT32 path_len)
{
UNUSED(context);
@ -233,7 +228,7 @@ FORT_API FORT_APP_ENTRY fort_conf_app_exe_find(
conf, path, path_len, conf->exe_apps_off, conf->exe_apps_n, fort_conf_app_exe_equal);
}
static FORT_APP_ENTRY fort_conf_app_wild_find(
static FORT_APP_DATA fort_conf_app_wild_find(
const PFORT_CONF conf, const PVOID path, UINT32 path_len)
{
return fort_conf_app_find_loop(
@ -242,19 +237,17 @@ static FORT_APP_ENTRY fort_conf_app_wild_find(
static int fort_conf_app_prefix_cmp(PFORT_APP_ENTRY app_entry, const PVOID path, UINT32 path_len)
{
const PVOID app_path = app_entry + 1;
const UINT32 app_path_len = app_entry->path_len;
if (path_len > app_path_len)
path_len = app_path_len;
return fort_memcmp(path, app_path, path_len);
if (path_len > app_entry->path_len) {
path_len = app_entry->path_len;
}
static FORT_APP_ENTRY fort_conf_app_prefix_find(
return fort_memcmp(path, app_entry->path, path_len);
}
static FORT_APP_DATA fort_conf_app_prefix_find(
const PFORT_CONF conf, const PVOID path, UINT32 path_len)
{
const FORT_APP_ENTRY app_data = { 0 };
const FORT_APP_DATA app_data = { 0 };
const UINT16 count = conf->prefix_apps_n;
if (count == 0)
@ -279,29 +272,29 @@ static FORT_APP_ENTRY fort_conf_app_prefix_find(
} else if (res > 0) {
low = mid + 1;
} else {
return *app_entry;
return app_entry->app_data;
}
} while (low <= high);
return app_data;
}
FORT_API FORT_APP_ENTRY fort_conf_app_find(const PFORT_CONF conf, const PVOID path, UINT32 path_len,
FORT_API FORT_APP_DATA fort_conf_app_find(const PFORT_CONF conf, const PVOID path, UINT32 path_len,
fort_conf_app_exe_find_func *exe_find_func, PVOID exe_context)
{
FORT_APP_ENTRY app_entry;
FORT_APP_DATA app_data;
app_entry = exe_find_func(conf, exe_context, path, path_len);
if (app_entry.flags.v != 0)
return app_entry;
app_data = exe_find_func(conf, exe_context, path, path_len);
if (app_data.flags.v != 0)
return app_data;
app_entry = fort_conf_app_wild_find(conf, path, path_len);
if (app_entry.flags.v != 0)
return app_entry;
app_data = fort_conf_app_wild_find(conf, path, path_len);
if (app_data.flags.v != 0)
return app_data;
app_entry = fort_conf_app_prefix_find(conf, path, path_len);
app_data = fort_conf_app_prefix_find(conf, path, path_len);
return app_entry;
return app_data;
}
static BOOL fort_conf_app_blocked_check(const PFORT_CONF conf, INT8 *block_reason, BOOL app_found,

View File

@ -17,8 +17,6 @@
#define FORT_CONF_STR_ALIGN 4
#define FORT_CONF_STR_HEADER_SIZE(n) (((n) + 1) * sizeof(UINT32))
#define FORT_CONF_STR_DATA_SIZE(size) FORT_ALIGN_SIZE((size), FORT_CONF_STR_ALIGN)
#define FORT_CONF_APP_ENTRY_SIZE(path_len) \
(sizeof(FORT_APP_ENTRY) + (path_len) + sizeof(WCHAR)) /* include terminating zero */
typedef struct fort_conf_flags
{
@ -181,14 +179,29 @@ typedef struct fort_app_flags
};
} FORT_APP_FLAGS, *PFORT_APP_FLAGS;
typedef struct fort_app_entry
typedef struct fort_app_data
{
FORT_APP_FLAGS flags;
UINT16 path_len;
UINT16 rule_id;
UINT16 accept_zones;
UINT16 reject_zones;
} FORT_APP_DATA, *PFORT_APP_DATA;
typedef struct fort_app_entry
{
FORT_APP_DATA app_data;
UINT16 path_len;
WCHAR path[2];
} FORT_APP_ENTRY, *PFORT_APP_ENTRY;
#define FORT_CONF_APP_ENTRY_PATH_OFF offsetof(FORT_APP_ENTRY, path)
#define FORT_CONF_APP_ENTRY_SIZE(path_len) \
(FORT_CONF_APP_ENTRY_PATH_OFF + (path_len) + sizeof(WCHAR)) /* include terminating zero */
typedef struct fort_speed_limit
{
UINT16 plr; /* packet loss rate in 1/100% (0-10000, i.e. 10% packet loss = 1000) */
@ -264,7 +277,7 @@ typedef struct fort_conf_io
#define FORT_CONF_ADDR_LIST_SIZE(ip4_n, pair4_n, ip6_n, pair6_n) \
(FORT_CONF_ADDR4_LIST_SIZE(ip4_n, pair4_n) + FORT_CONF_ADDR6_LIST_SIZE(ip6_n, pair6_n))
typedef FORT_APP_ENTRY fort_conf_app_exe_find_func(
typedef FORT_APP_DATA fort_conf_app_exe_find_func(
const PFORT_CONF conf, PVOID context, const PVOID path, UINT32 path_len);
typedef BOOL fort_conf_zones_ip_included_func(
@ -301,10 +314,10 @@ FORT_API BOOL fort_conf_ip_included(const PFORT_CONF conf,
FORT_API BOOL fort_conf_app_exe_equal(
const PFORT_APP_ENTRY app_entry, const PVOID path, UINT32 path_len);
FORT_API FORT_APP_ENTRY fort_conf_app_exe_find(
FORT_API FORT_APP_DATA fort_conf_app_exe_find(
const PFORT_CONF conf, PVOID context, const PVOID path, UINT32 path_len);
FORT_API FORT_APP_ENTRY fort_conf_app_find(const PFORT_CONF conf, const PVOID path, UINT32 path_len,
FORT_API FORT_APP_DATA fort_conf_app_find(const PFORT_CONF conf, const PVOID path, UINT32 path_len,
fort_conf_app_exe_find_func *exe_find_func, PVOID exe_context);
FORT_API BOOL fort_conf_app_blocked(

View File

@ -74,14 +74,15 @@ static PFORT_CONF_EXE_NODE fort_conf_ref_exe_find_node(
return NULL;
}
FORT_API FORT_APP_ENTRY fort_conf_exe_find(
FORT_API FORT_APP_DATA fort_conf_exe_find(
const PFORT_CONF conf, PVOID context, const PVOID path, UINT32 path_len)
{
UNUSED(conf);
PFORT_CONF_REF conf_ref = context;
const tommy_key_t path_hash = (tommy_key_t) tommy_hash_u64(0, path, path_len);
FORT_APP_ENTRY app_data;
app_data.flags.v = 0;
FORT_APP_DATA app_data = { 0 };
KIRQL oldIrql = ExAcquireSpinLockShared(&conf_ref->conf_lock);
{
@ -89,7 +90,7 @@ FORT_API FORT_APP_ENTRY fort_conf_exe_find(
fort_conf_ref_exe_find_node(conf_ref, path, path_len, path_hash);
if (node != NULL) {
app_data = *node->app_entry;
app_data = node->app_entry->app_data;
}
}
ExReleaseSpinLockShared(&conf_ref->conf_lock, oldIrql);
@ -157,7 +158,7 @@ static NTSTATUS fort_conf_ref_exe_add_path_locked(PFORT_CONF_REF conf_ref,
return fort_conf_ref_exe_new_entry(conf_ref, app_entry, path, path_hash);
}
if (app_entry->flags.is_new)
if (app_entry->app_data.flags.is_new)
return FORT_STATUS_USER_ERROR;
/* Replace the data */

View File

@ -53,7 +53,7 @@ FORT_API UCHAR fort_device_flag_set(PFORT_DEVICE_CONF device_conf, UCHAR flag, B
FORT_API UCHAR fort_device_flag(PFORT_DEVICE_CONF device_conf, UCHAR flag);
FORT_API FORT_APP_ENTRY fort_conf_exe_find(
FORT_API FORT_APP_DATA fort_conf_exe_find(
const PFORT_CONF conf, PVOID context, const PVOID path, UINT32 path_len);
FORT_API NTSTATUS fort_conf_ref_exe_add_path(

View File

@ -47,19 +47,19 @@ static void fort_callout_classify_continue(FWPS_CLASSIFY_OUT0 *classifyOut)
}
inline static void fort_callout_ale_set_app_flags(
PFORT_CALLOUT_ALE_EXTRA cx, FORT_APP_ENTRY app_data)
PFORT_CALLOUT_ALE_EXTRA cx, FORT_APP_DATA app_data)
{
cx->app_data_found = TRUE;
cx->app_data = app_data;
}
static FORT_APP_ENTRY fort_callout_ale_conf_app_data(
static FORT_APP_DATA fort_callout_ale_conf_app_data(
PFORT_CALLOUT_ALE_EXTRA cx, PFORT_CONF_REF conf_ref)
{
if (cx->app_data_found)
return cx->app_data;
const FORT_APP_ENTRY app_data = fort_conf_app_find(
const FORT_APP_DATA app_data = fort_conf_app_find(
&conf_ref->conf, cx->path->Buffer, cx->path->Length, fort_conf_exe_find, conf_ref);
fort_callout_ale_set_app_flags(cx, app_data);
@ -109,7 +109,7 @@ inline static BOOL fort_callout_ale_log_app_path_check(
}
inline static void fort_callout_ale_log_app_path(PFORT_CALLOUT_ALE_EXTRA cx,
PFORT_CONF_REF conf_ref, FORT_CONF_FLAGS conf_flags, FORT_APP_ENTRY app_data)
PFORT_CONF_REF conf_ref, FORT_CONF_FLAGS conf_flags, FORT_APP_DATA app_data)
{
if (cx->ignore || !fort_callout_ale_log_app_path_check(conf_flags, app_data.flags))
return;
@ -120,9 +120,12 @@ inline static void fort_callout_ale_log_app_path(PFORT_CALLOUT_ALE_EXTRA cx,
app_data.flags.alerted = TRUE;
app_data.flags.is_new = TRUE;
app_data.path_len = cx->path->Length;
FORT_APP_ENTRY app_entry = {
.app_data = app_data,
.path_len = cx->path->Length,
};
if (!NT_SUCCESS(fort_conf_ref_exe_add_path(conf_ref, &app_data, cx->path->Buffer)))
if (!NT_SUCCESS(fort_conf_ref_exe_add_path(conf_ref, &app_entry, cx->path->Buffer)))
return;
fort_callout_ale_set_app_flags(cx, app_data);
@ -147,7 +150,7 @@ inline static BOOL fort_callout_ale_log_blocked_ip_check(
if (!(conf_flags.ask_to_connect || conf_flags.log_blocked_ip))
return FALSE;
const FORT_APP_ENTRY app_data = fort_callout_ale_conf_app_data(cx, conf_ref);
const FORT_APP_DATA app_data = fort_callout_ale_conf_app_data(cx, conf_ref);
return fort_callout_ale_log_blocked_ip_check_app(conf_flags, app_data.flags);
}
@ -198,8 +201,8 @@ inline static BOOL fort_callout_ale_process_flow(PCFORT_CALLOUT_ARG ca, PFORT_CA
return fort_callout_ale_associate_flow(ca, cx, conf_ref, app_flags);
}
static BOOL fort_callout_ale_is_zone_blocked(PCFORT_CALLOUT_ARG ca, PFORT_CALLOUT_ALE_EXTRA cx,
PFORT_CONF_REF conf_ref, FORT_APP_ENTRY app_data)
static BOOL fort_callout_ale_is_zone_blocked(
PCFORT_CALLOUT_ARG ca, PFORT_CALLOUT_ALE_EXTRA cx, FORT_APP_DATA app_data)
{
const BOOL app_found = (app_data.flags.v != 0);
if (!app_found)
@ -227,7 +230,7 @@ static BOOL fort_callout_ale_is_zone_blocked(PCFORT_CALLOUT_ARG ca, PFORT_CALLOU
return FALSE;
}
inline static BOOL fort_callout_ale_is_new(FORT_CONF_FLAGS conf_flags, FORT_APP_ENTRY app_data)
inline static BOOL fort_callout_ale_is_new(FORT_CONF_FLAGS conf_flags, FORT_APP_DATA app_data)
{
const BOOL app_found = (app_data.flags.v != 0);
@ -235,7 +238,7 @@ inline static BOOL fort_callout_ale_is_new(FORT_CONF_FLAGS conf_flags, FORT_APP_
}
inline static BOOL fort_callout_ale_is_allowed(PCFORT_CALLOUT_ARG ca, PFORT_CALLOUT_ALE_EXTRA cx,
PFORT_CONF_REF conf_ref, FORT_CONF_FLAGS conf_flags, FORT_APP_ENTRY app_data)
PFORT_CONF_REF conf_ref, FORT_CONF_FLAGS conf_flags, FORT_APP_DATA app_data)
{
/* Collect traffic, when Filter Disabled */
if (!cx->blocked)
@ -246,7 +249,7 @@ inline static BOOL fort_callout_ale_is_allowed(PCFORT_CALLOUT_ARG ca, PFORT_CALL
return TRUE;
/* Check LAN Only and Zones */
if (fort_callout_ale_is_zone_blocked(ca, cx, conf_ref, app_data))
if (fort_callout_ale_is_zone_blocked(ca, cx, app_data))
return FALSE;
/* Check the conf for a blocked app */
@ -263,7 +266,7 @@ inline static BOOL fort_callout_ale_is_allowed(PCFORT_CALLOUT_ARG ca, PFORT_CALL
inline static void fort_callout_ale_log(PCFORT_CALLOUT_ARG ca, PFORT_CALLOUT_ALE_EXTRA cx,
PFORT_CONF_REF conf_ref, FORT_CONF_FLAGS conf_flags)
{
const FORT_APP_ENTRY app_data = fort_callout_ale_conf_app_data(cx, conf_ref);
const FORT_APP_DATA app_data = fort_callout_ale_conf_app_data(cx, conf_ref);
if (fort_callout_ale_is_allowed(ca, cx, conf_ref, conf_flags, app_data)) {

View File

@ -48,7 +48,7 @@ typedef struct fort_callout_ale_extra
UCHAR ignore : 1;
INT8 block_reason;
FORT_APP_ENTRY app_data;
FORT_APP_DATA app_data;
UINT32 process_id;

View File

@ -429,7 +429,7 @@ inline static void fort_pstree_check_proc_conf(
const PFORT_CONF conf = &conf_ref->conf;
const FORT_APP_ENTRY app_data = conf->proc_wild
const FORT_APP_DATA app_data = conf->proc_wild
? fort_conf_app_find(conf, path_buf, path_len, fort_conf_exe_find, conf_ref)
: fort_conf_exe_find(conf, conf_ref, path_buf, path_len);

View File

@ -224,7 +224,7 @@ quint16 confAppFind(const void *drvConf, const QString &kernelPath)
const quint32 len = quint32(kernelPathLower.size()) * sizeof(WCHAR);
const WCHAR *p = (PCWCHAR) kernelPathLower.utf16();
const FORT_APP_ENTRY app_data = fort_conf_app_find(
const FORT_APP_DATA app_data = fort_conf_app_find(
conf, (const PVOID) p, len, fort_conf_app_exe_find, /*exe_context=*/nullptr);
return app_data.flags.v;

View File

@ -1,6 +1,6 @@
#include "appparseoptions.h"
appentry_map_t &AppParseOptions::appsMap(bool isWild, bool isPrefix)
appdata_map_t &AppParseOptions::appsMap(bool isWild, bool isPrefix)
{
return isWild ? wildAppsMap : (isPrefix ? prefixAppsMap : exeAppsMap);
}

View File

@ -10,12 +10,12 @@
#include "addressrange.h"
using addrranges_arr_t = QVarLengthArray<AddressRange, 2>;
using appentry_map_t = QMap<QString, FORT_APP_ENTRY>;
using appdata_map_t = QMap<QString, FORT_APP_DATA>;
class AppParseOptions
{
public:
appentry_map_t &appsMap(bool isWild, bool isPrefix);
appdata_map_t &appsMap(bool isWild, bool isPrefix);
quint32 &appsSize(bool isWild, bool isPrefix);
public:
@ -25,9 +25,9 @@ public:
quint32 prefixAppsSize = 0;
quint32 exeAppsSize = 0;
appentry_map_t wildAppsMap;
appentry_map_t prefixAppsMap;
appentry_map_t exeAppsMap;
appdata_map_t wildAppsMap;
appdata_map_t prefixAppsMap;
appdata_map_t exeAppsMap;
};
#endif // APPPARSEOPTIONS_H

View File

@ -190,7 +190,7 @@ int ConfUtil::writeFlags(const FirewallConf &conf, QByteArray &buf)
int ConfUtil::writeAppEntry(const App &app, bool isNew, QByteArray &buf)
{
appentry_map_t appsMap;
appdata_map_t appsMap;
quint32 appsSize = 0;
if (!addApp(app, isNew, appsMap, appsSize))
@ -442,13 +442,13 @@ bool ConfUtil::parseAppLine(App &app, const QStringView &line, AppParseOptions &
}
}
appentry_map_t &appsMap = opt.appsMap(isWild, isPrefix);
appdata_map_t &appsMap = opt.appsMap(isWild, isPrefix);
quint32 &appsSize = opt.appsSize(isWild, isPrefix);
return addApp(app, /*isNew=*/true, appsMap, appsSize);
}
bool ConfUtil::addApp(const App &app, bool isNew, appentry_map_t &appsMap, quint32 &appsSize)
bool ConfUtil::addApp(const App &app, bool isNew, appdata_map_t &appsMap, quint32 &appsSize)
{
const QString kernelPath = FileUtil::pathToKernelPath(app.appPath);
@ -465,7 +465,7 @@ bool ConfUtil::addApp(const App &app, bool isNew, appentry_map_t &appsMap, quint
appsSize += appSize;
const FORT_APP_ENTRY appEntry = {
const FORT_APP_DATA appEntry = {
.flags = {
.group_index = quint8(app.groupIndex),
.use_group_perm = app.useGroupPerm,
@ -480,7 +480,7 @@ bool ConfUtil::addApp(const App &app, bool isNew, appentry_map_t &appsMap, quint
.is_new = isNew,
.found = 1,
},
.path_len = appPathLen,
.rule_id = app.ruleId,
.accept_zones = quint16(app.acceptZones),
.reject_zones = quint16(app.rejectZones),
};
@ -783,7 +783,7 @@ bool ConfUtil::loadAddress6List(const char **data, IpRange &ipRange, uint &bufSi
return true;
}
void ConfUtil::writeApps(char **data, const appentry_map_t &appsMap, bool useHeader)
void ConfUtil::writeApps(char **data, const appdata_map_t &appsMap, bool useHeader)
{
quint32 *offp = (quint32 *) *data;
const quint32 offTableSize = quint32(useHeader ? FORT_CONF_STR_HEADER_SIZE(appsMap.size()) : 0);
@ -797,18 +797,19 @@ void ConfUtil::writeApps(char **data, const appentry_map_t &appsMap, bool useHea
auto it = appsMap.constBegin();
const auto end = appsMap.constEnd();
for (; it != end; ++it) {
const QString &appPath = it.key();
const QString &kernelPath = it.key();
const FORT_APP_ENTRY &appEntry = it.value();
const quint16 appPathLen = quint16(kernelPath.size()) * sizeof(wchar_t);
const quint32 appSize = FORT_CONF_APP_ENTRY_SIZE(appPathLen);
const FORT_APP_DATA &appData = it.value();
PFORT_APP_ENTRY entry = (PFORT_APP_ENTRY) p;
*entry++ = appEntry;
entry->app_data = appData;
entry->path_len = appPathLen;
wchar_t *pathArray = (wchar_t *) entry;
appPath.toWCharArray(pathArray);
pathArray[appEntry.path_len / sizeof(wchar_t)] = '\0';
const quint32 appSize = FORT_CONF_APP_ENTRY_SIZE(appEntry.path_len);
kernelPath.toWCharArray(entry->path);
entry->path[kernelPath.size()] = '\0';
off += appSize;
if (useHeader) {

View File

@ -72,7 +72,7 @@ private:
bool parseAppLine(App &app, const QStringView &line, AppParseOptions &opt);
bool addApp(const App &app, bool isNew, appentry_map_t &appsMap, quint32 &appsSize);
bool addApp(const App &app, bool isNew, appdata_map_t &appsMap, quint32 &appsSize);
static QString parseAppPath(const QStringView line, bool &isWild, bool &isPrefix);
@ -102,7 +102,7 @@ private:
static bool loadAddress4List(const char **data, IpRange &ipRange, uint &bufSize);
static bool loadAddress6List(const char **data, IpRange &ipRange, uint &bufSize);
static void writeApps(char **data, const appentry_map_t &appsMap, bool useHeader = false);
static void writeApps(char **data, const appdata_map_t &appsMap, bool useHeader = false);
static void writeShorts(char **data, const shorts_arr_t &array);
static void writeLongs(char **data, const longs_arr_t &array);