mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-14 06:13:09 +00:00
nfqws2: move ctx from lightuserdata to userdata. prevents crashes on specific ARM cpus
This commit is contained in:
@@ -174,3 +174,4 @@ v0.8.1
|
||||
|
||||
* winws2: fix loopback large packets processing (up to 64K)
|
||||
* zapret-lib, zapret-antidpi: use numeric indexes in http dissects
|
||||
* nfqws2: move ctx from lightuserdata to userdata. prevents crashes on specific ARM cpus
|
||||
|
||||
@@ -753,7 +753,6 @@ static uint8_t desync(
|
||||
struct func_list *func;
|
||||
int ref_arg = LUA_NOREF, status;
|
||||
bool b, b_cutoff_all, b_unwanted_payload;
|
||||
t_lua_desync_context ctx = { .magic = 0, .dp = dp, .ctrack = ctrack, .dis = dis, .cancel = false, .incoming = bIncoming };
|
||||
const char *sDirection = bIncoming ? "in" : "out";
|
||||
struct packet_range *range;
|
||||
size_t l;
|
||||
@@ -782,13 +781,19 @@ static uint8_t desync(
|
||||
|
||||
if (LIST_FIRST(&dp->lua_desync))
|
||||
{
|
||||
params.desync_ctx->dp = dp;
|
||||
params.desync_ctx->ctrack = ctrack;
|
||||
params.desync_ctx->dis = dis;
|
||||
params.desync_ctx->cancel = false;
|
||||
params.desync_ctx->incoming = bIncoming;
|
||||
|
||||
b_cutoff_all = b_unwanted_payload = true;
|
||||
ctx.func_n = 1;
|
||||
params.desync_ctx->func_n = 1;
|
||||
LIST_FOREACH(func, &dp->lua_desync, next)
|
||||
{
|
||||
ctx.func = func->func;
|
||||
desync_instance(func->func, dp->n, ctx.func_n, instance, sizeof(instance));
|
||||
ctx.instance = instance;
|
||||
params.desync_ctx->func = func->func;
|
||||
desync_instance(func->func, dp->n, params.desync_ctx->func_n, instance, sizeof(instance));
|
||||
params.desync_ctx->instance = instance;
|
||||
range = bIncoming ? &func->range_in : &func->range_out;
|
||||
|
||||
if (b_unwanted_payload)
|
||||
@@ -796,7 +801,7 @@ static uint8_t desync(
|
||||
|
||||
if (b_cutoff_all)
|
||||
{
|
||||
if (lua_instance_cutoff_check(params.L, &ctx, bIncoming))
|
||||
if (lua_instance_cutoff_check(params.L, params.desync_ctx, bIncoming))
|
||||
DLOG("* lua '%s' : voluntary cutoff\n", instance);
|
||||
else if (check_pos_cutoff(pos, range))
|
||||
{
|
||||
@@ -814,7 +819,7 @@ static uint8_t desync(
|
||||
else
|
||||
b_cutoff_all = false;
|
||||
}
|
||||
ctx.func_n++;
|
||||
params.desync_ctx->func_n++;
|
||||
}
|
||||
if (b_cutoff_all)
|
||||
{
|
||||
@@ -867,14 +872,14 @@ static uint8_t desync(
|
||||
}
|
||||
ref_arg = luaL_ref(params.L, LUA_REGISTRYINDEX);
|
||||
|
||||
ctx.func_n = 1;
|
||||
params.desync_ctx->func_n = 1;
|
||||
LIST_FOREACH(func, &dp->lua_desync, next)
|
||||
{
|
||||
ctx.func = func->func;
|
||||
desync_instance(func->func, dp->n, ctx.func_n, instance, sizeof(instance));
|
||||
ctx.instance = instance;
|
||||
params.desync_ctx->func = func->func;
|
||||
desync_instance(func->func, dp->n, params.desync_ctx->func_n, instance, sizeof(instance));
|
||||
params.desync_ctx->instance = instance;
|
||||
|
||||
if (!lua_instance_cutoff_check(params.L, &ctx, bIncoming))
|
||||
if (!lua_instance_cutoff_check(params.L, params.desync_ctx, bIncoming))
|
||||
{
|
||||
range = bIncoming ? &func->range_in : &func->range_out;
|
||||
if (check_pos_range(pos, range))
|
||||
@@ -897,19 +902,16 @@ static uint8_t desync(
|
||||
DLOG_ERR("desync function '%s' does not exist\n", func->func);
|
||||
goto err;
|
||||
}
|
||||
lua_pushlightuserdata(params.L, &ctx);
|
||||
lua_rawgeti(params.L, LUA_REGISTRYINDEX, params.ref_desync_ctx);
|
||||
lua_rawgeti(params.L, LUA_REGISTRYINDEX, ref_arg);
|
||||
lua_pushf_args(params.L, &func->args, -1, true);
|
||||
lua_pushf_str(params.L, "func", func->func);
|
||||
lua_pushf_int(params.L, "func_n", ctx.func_n);
|
||||
lua_pushf_int(params.L, "func_n", params.desync_ctx->func_n);
|
||||
lua_pushf_str(params.L, "func_instance", instance);
|
||||
|
||||
// lua should not store and access ctx outside of this call
|
||||
// if this happens make our best to prevent access to bad memory
|
||||
// this is not crash-proof but better than nothing
|
||||
ctx.magic = MAGIC_CTX; // mark struct as valid
|
||||
// prevent use of desync ctx object outside of function call
|
||||
params.desync_ctx->valid = true;
|
||||
status = lua_pcall(params.L, 2, LUA_MULTRET, 0);
|
||||
ctx.magic = 0; // mark struct as invalid
|
||||
params.desync_ctx->valid = false;
|
||||
|
||||
if (status)
|
||||
{
|
||||
@@ -939,8 +941,8 @@ static uint8_t desync(
|
||||
range->upper_cutoff ? '<' : '-',
|
||||
range->to.mode, range->to.pos);
|
||||
}
|
||||
if (ctx.cancel) break;
|
||||
ctx.func_n++;
|
||||
if (params.desync_ctx->cancel) break;
|
||||
params.desync_ctx->func_n++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
59
nfq2/lua.c
59
nfq2/lua.c
@@ -769,20 +769,42 @@ static int luacall_clock_gettime(lua_State *L)
|
||||
LUA_STACK_GUARD_RETURN(L,2)
|
||||
}
|
||||
|
||||
static void lua_mt_init_desync_ctx(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, "desync_ctx");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
static t_lua_desync_context *lua_desync_ctx(lua_State *L)
|
||||
{
|
||||
if (lua_isnil(L,1))
|
||||
luaL_error(L, "missing ctx");
|
||||
if (!lua_islightuserdata(L,1))
|
||||
luaL_error(L, "bad ctx - invalid data type");
|
||||
|
||||
t_lua_desync_context *ctx = lua_touserdata(L,1);
|
||||
// ensure it's really ctx. LUA could pass us any lightuserdata pointer
|
||||
if (ctx->magic!=MAGIC_CTX)
|
||||
luaL_error(L, "bad ctx - magic bytes invalid");
|
||||
|
||||
if (lua_isnil(L,1)) luaL_error(L, "missing ctx");
|
||||
t_lua_desync_context *ctx = (t_lua_desync_context *)luaL_checkudata(L, 1, "desync_ctx");
|
||||
if (!ctx->valid) luaL_error(L, "ctx is invalid");
|
||||
return ctx;
|
||||
}
|
||||
static void lua_desync_ctx_create(lua_State *L)
|
||||
{
|
||||
if (!params.ref_desync_ctx)
|
||||
{
|
||||
LUA_STACK_GUARD_ENTER(L)
|
||||
|
||||
params.desync_ctx = (t_lua_desync_context *)lua_newuserdata(L, sizeof(t_lua_desync_context));
|
||||
memset(params.desync_ctx, 0, sizeof(t_lua_desync_context));
|
||||
luaL_getmetatable(L, "desync_ctx");
|
||||
lua_setmetatable(L, -2);
|
||||
params.ref_desync_ctx = luaL_ref(params.L, LUA_REGISTRYINDEX);
|
||||
|
||||
LUA_STACK_GUARD_LEAVE(L,0)
|
||||
}
|
||||
}
|
||||
static void lua_desync_ctx_destroy(lua_State *L)
|
||||
{
|
||||
if (params.ref_desync_ctx)
|
||||
{
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, params.ref_desync_ctx);
|
||||
params.ref_desync_ctx = 0;
|
||||
params.desync_ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int luacall_instance_cutoff(lua_State *L)
|
||||
{
|
||||
@@ -2846,14 +2868,19 @@ zerr:
|
||||
|
||||
// ----------------------------------------
|
||||
|
||||
void lua_cleanup(lua_State *L)
|
||||
{
|
||||
lua_desync_ctx_destroy(L);
|
||||
// conntrack holds lua state. must clear it before lua shoudown
|
||||
ConntrackPoolDestroy(¶ms.conntrack);
|
||||
}
|
||||
|
||||
void lua_shutdown()
|
||||
{
|
||||
if (params.L)
|
||||
{
|
||||
DLOG("LUA SHUTDOWN\n");
|
||||
// conntrack holds lua state. must clear it before lua shoudown
|
||||
ConntrackPoolDestroy(¶ms.conntrack);
|
||||
lua_cleanup(params.L);
|
||||
lua_close(params.L);
|
||||
params.L=NULL;
|
||||
}
|
||||
@@ -3396,6 +3423,8 @@ static void lua_init_functions(void)
|
||||
static void lua_init_mt()
|
||||
{
|
||||
lua_mt_init_zstream(params.L);
|
||||
lua_mt_init_desync_ctx(params.L);
|
||||
lua_desync_ctx_create(params.L);
|
||||
}
|
||||
|
||||
bool lua_init(void)
|
||||
@@ -3403,6 +3432,9 @@ bool lua_init(void)
|
||||
DLOG("\nLUA INIT\n");
|
||||
|
||||
if (!lua_basic_init()) return false;
|
||||
|
||||
LUA_STACK_GUARD_ENTER(params.L)
|
||||
|
||||
lua_sec_harden();
|
||||
lua_init_blobs();
|
||||
lua_init_const();
|
||||
@@ -3411,10 +3443,11 @@ bool lua_init(void)
|
||||
if (!lua_init_scripts()) goto err;
|
||||
if (!lua_desync_functions_exist()) goto err;
|
||||
|
||||
LUA_STACK_GUARD_LEAVE(params.L,0)
|
||||
DLOG("LUA INIT DONE\n\n");
|
||||
|
||||
return true;
|
||||
err:
|
||||
LUA_STACK_GUARD_LEAVE(params.L,0)
|
||||
lua_shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
12
nfq2/lua.h
12
nfq2/lua.h
@@ -14,6 +14,7 @@
|
||||
#include "pools.h"
|
||||
#include "conntrack.h"
|
||||
#include "darkmagic.h"
|
||||
#include "params.h"
|
||||
|
||||
#if LUA_VERSION_NUM < 503
|
||||
#define lua_isinteger lua_isnumber
|
||||
@@ -101,15 +102,4 @@ bool lua_reconstruct_tcphdr(lua_State *L, int idx, struct tcphdr *tcp, size_t *l
|
||||
bool lua_reconstruct_udphdr(lua_State *L, int idx, struct udphdr *udp);
|
||||
bool lua_reconstruct_dissect(lua_State *L, int idx, uint8_t *buf, size_t *len, bool badsum, bool ip6_preserve_next);
|
||||
|
||||
#define MAGIC_CTX 0xE73DC935
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
unsigned int func_n;
|
||||
const char *func, *instance;
|
||||
const struct desync_profile *dp;
|
||||
const struct dissect *dis;
|
||||
t_ctrack *ctrack;
|
||||
bool incoming,cancel;
|
||||
} t_lua_desync_context;
|
||||
|
||||
bool lua_instance_cutoff_check(lua_State *L, const t_lua_desync_context *ctx, bool bIn);
|
||||
|
||||
@@ -498,6 +498,9 @@ void cleanup_params(struct params_s *params)
|
||||
ipcacheDestroy(¶ms->ipcache);
|
||||
blob_collection_destroy(¶ms->blobs);
|
||||
strlist_destroy(¶ms->lua_init_scripts);
|
||||
|
||||
params->desync_ctx = NULL;
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
strlist_destroy(¶ms->ssid_filter);
|
||||
strlist_destroy(¶ms->nlm_filter);
|
||||
|
||||
@@ -115,6 +115,16 @@ void dp_clear(struct desync_profile *dp);
|
||||
#define WINDIVERT_MAX 65536
|
||||
#define WINDIVERT_PORTFILTER_MAX 4096
|
||||
|
||||
typedef struct {
|
||||
unsigned int func_n;
|
||||
const char *func, *instance;
|
||||
const struct desync_profile *dp;
|
||||
const struct dissect *dis;
|
||||
t_ctrack *ctrack;
|
||||
bool incoming, cancel;
|
||||
bool valid;
|
||||
} t_lua_desync_context;
|
||||
|
||||
struct params_s
|
||||
{
|
||||
#if !defined( __OpenBSD__) && !defined(__ANDROID__)
|
||||
@@ -182,6 +192,8 @@ struct params_s
|
||||
char writeable_dir[PATH_MAX];
|
||||
|
||||
int lua_gc;
|
||||
int ref_desync_ctx; // desync ctx userdata registry ref
|
||||
t_lua_desync_context *desync_ctx; // desync ctx single object
|
||||
lua_State *L;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user