Skip to content

Commit 6e671f1

Browse files
authored
[Medium] patch ntopng for CVE-2021-44964 (#13450)
1 parent 5ddc12c commit 6e671f1

File tree

2 files changed

+396
-1
lines changed

2 files changed

+396
-1
lines changed

SPECS/ntopng/CVE-2021-44964.patch

Lines changed: 391 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,391 @@
1+
From a5e6f4a7711410d0e43943809021462199c0c36a Mon Sep 17 00:00:00 2001
2+
From: jykanase <[email protected]>
3+
Date: Thu, 15 May 2025 15:36:50 +0000
4+
Subject: [PATCH] CVE-2021-44964
5+
Upstream patch reference: https://github.com/lua/lua/commit/0bfc572e51d9035a615ef6e9523f736c9ffa8e57
6+
---
7+
third-party/lua-5.4.3/src/lapi.c | 17 ++++-----
8+
third-party/lua-5.4.3/src/lbaselib.c | 19 ++++++++--
9+
third-party/lua-5.4.3/src/ldebug.c | 54 +++++++++++++++++-----------
10+
third-party/lua-5.4.3/src/lgc.c | 17 +++++----
11+
third-party/lua-5.4.3/src/lgc.h | 10 ++++++
12+
third-party/lua-5.4.3/src/llimits.h | 2 +-
13+
third-party/lua-5.4.3/src/lstate.c | 4 +--
14+
third-party/lua-5.4.3/src/lstate.h | 4 +--
15+
8 files changed, 84 insertions(+), 43 deletions(-)
16+
17+
diff --git a/third-party/lua-5.4.3/src/lapi.c b/third-party/lua-5.4.3/src/lapi.c
18+
index f8f70cd..b7e4711 100644
19+
--- a/third-party/lua-5.4.3/src/lapi.c
20+
+++ b/third-party/lua-5.4.3/src/lapi.c
21+
@@ -1126,18 +1126,19 @@ LUA_API int lua_status (lua_State *L) {
22+
LUA_API int lua_gc (lua_State *L, int what, ...) {
23+
va_list argp;
24+
int res = 0;
25+
- global_State *g;
26+
+ global_State *g = G(L);
27+
+ if (g->gcstp & GCSTPGC) /* internal stop? */
28+
+ return -1; /* all options are invalid when stopped */
29+
lua_lock(L);
30+
- g = G(L);
31+
va_start(argp, what);
32+
switch (what) {
33+
case LUA_GCSTOP: {
34+
- g->gcrunning = 0;
35+
+ g->gcstp = GCSTPUSR; /* stopped by the user */
36+
break;
37+
}
38+
case LUA_GCRESTART: {
39+
luaE_setdebt(g, 0);
40+
- g->gcrunning = 1;
41+
+ g->gcstp = 0; /* (GCSTPGC must be already zero here) */
42+
break;
43+
}
44+
case LUA_GCCOLLECT: {
45+
@@ -1156,8 +1157,8 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
46+
case LUA_GCSTEP: {
47+
int data = va_arg(argp, int);
48+
l_mem debt = 1; /* =1 to signal that it did an actual step */
49+
- lu_byte oldrunning = g->gcrunning;
50+
- g->gcrunning = 1; /* allow GC to run */
51+
+ lu_byte oldstp = g->gcstp;
52+
+ g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */
53+
if (data == 0) {
54+
luaE_setdebt(g, 0); /* do a basic step */
55+
luaC_step(L);
56+
@@ -1167,7 +1168,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
57+
luaE_setdebt(g, debt);
58+
luaC_checkGC(L);
59+
}
60+
- g->gcrunning = oldrunning; /* restore previous state */
61+
+ g->gcstp = oldstp; /* restore previous state */
62+
if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
63+
res = 1; /* signal it */
64+
break;
65+
@@ -1185,7 +1186,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
66+
break;
67+
}
68+
case LUA_GCISRUNNING: {
69+
- res = g->gcrunning;
70+
+ res = gcrunning(g);
71+
break;
72+
}
73+
case LUA_GCGEN: {
74+
diff --git a/third-party/lua-5.4.3/src/lbaselib.c b/third-party/lua-5.4.3/src/lbaselib.c
75+
index 83ad306..82abd94 100644
76+
--- a/third-party/lua-5.4.3/src/lbaselib.c
77+
+++ b/third-party/lua-5.4.3/src/lbaselib.c
78+
@@ -182,12 +182,20 @@ static int luaB_rawset (lua_State *L) {
79+
80+
81+
static int pushmode (lua_State *L, int oldmode) {
82+
- lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental"
83+
- : "generational");
84+
+ if (oldmode == -1)
85+
+ luaL_pushfail(L); /* invalid call to 'lua_gc' */
86+
+ else
87+
+ lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental"
88+
+ : "generational");
89+
return 1;
90+
}
91+
92+
93+
+/*
94+
+** check whether call to 'lua_gc' was valid (not inside a finalizer)
95+
+*/
96+
+#define checkvalres(res) { if (res == -1) break; }
97+
+
98+
static int luaB_collectgarbage (lua_State *L) {
99+
static const char *const opts[] = {"stop", "restart", "collect",
100+
"count", "step", "setpause", "setstepmul",
101+
@@ -200,12 +208,14 @@ static int luaB_collectgarbage (lua_State *L) {
102+
case LUA_GCCOUNT: {
103+
int k = lua_gc(L, o);
104+
int b = lua_gc(L, LUA_GCCOUNTB);
105+
+ checkvalres(k);
106+
lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024));
107+
return 1;
108+
}
109+
case LUA_GCSTEP: {
110+
int step = (int)luaL_optinteger(L, 2, 0);
111+
int res = lua_gc(L, o, step);
112+
+ checkvalres(res);
113+
lua_pushboolean(L, res);
114+
return 1;
115+
}
116+
@@ -213,11 +223,13 @@ static int luaB_collectgarbage (lua_State *L) {
117+
case LUA_GCSETSTEPMUL: {
118+
int p = (int)luaL_optinteger(L, 2, 0);
119+
int previous = lua_gc(L, o, p);
120+
+ checkvalres(previous);
121+
lua_pushinteger(L, previous);
122+
return 1;
123+
}
124+
case LUA_GCISRUNNING: {
125+
int res = lua_gc(L, o);
126+
+ checkvalres(res);
127+
lua_pushboolean(L, res);
128+
return 1;
129+
}
130+
@@ -234,10 +246,13 @@ static int luaB_collectgarbage (lua_State *L) {
131+
}
132+
default: {
133+
int res = lua_gc(L, o);
134+
+ checkvalres(res);
135+
lua_pushinteger(L, res);
136+
return 1;
137+
}
138+
}
139+
+ luaL_pushfail(L); /* invalid call (inside a finalizer) */
140+
+ return 1;
141+
}
142+
143+
144+
diff --git a/third-party/lua-5.4.3/src/ldebug.c b/third-party/lua-5.4.3/src/ldebug.c
145+
index 1feaab2..ea269db 100644
146+
--- a/third-party/lua-5.4.3/src/ldebug.c
147+
+++ b/third-party/lua-5.4.3/src/ldebug.c
148+
@@ -34,8 +34,8 @@
149+
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL)
150+
151+
152+
-static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
153+
- const char **name);
154+
+static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
155+
+ const char **name);
156+
157+
158+
static int currentpc (CallInfo *ci) {
159+
@@ -310,15 +310,9 @@ static void collectvalidlines (lua_State *L, Closure *f) {
160+
161+
162+
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
163+
- if (ci == NULL) /* no 'ci'? */
164+
- return NULL; /* no info */
165+
- else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
166+
- *name = "__gc";
167+
- return "metamethod"; /* report it as such */
168+
- }
169+
- /* calling function is a known Lua function? */
170+
- else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
171+
- return funcnamefromcode(L, ci->previous, name);
172+
+ /* calling function is a known function? */
173+
+ if (ci != NULL && !(ci->callstatus & CIST_TAIL))
174+
+ return funcnamefromcall(L, ci->previous, name);
175+
else return NULL; /* no way to find a name */
176+
}
177+
178+
@@ -590,16 +584,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
179+
** Returns what the name is (e.g., "for iterator", "method",
180+
** "metamethod") and sets '*name' to point to the name.
181+
*/
182+
-static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
183+
- const char **name) {
184+
+static const char *funcnamefromcode (lua_State *L, const Proto *p,
185+
+ int pc, const char **name) {
186+
TMS tm = (TMS)0; /* (initial value avoids warnings) */
187+
- const Proto *p = ci_func(ci)->p; /* calling function */
188+
- int pc = currentpc(ci); /* calling instruction index */
189+
Instruction i = p->code[pc]; /* calling instruction */
190+
- if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
191+
- *name = "?";
192+
- return "hook";
193+
- }
194+
switch (GET_OPCODE(i)) {
195+
case OP_CALL:
196+
case OP_TAILCALL:
197+
@@ -636,6 +624,26 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
198+
return "metamethod";
199+
}
200+
201+
+
202+
+/*
203+
+** Try to find a name for a function based on how it was called.
204+
+*/
205+
+static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
206+
+ const char **name) {
207+
+ if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
208+
+ *name = "?";
209+
+ return "hook";
210+
+ }
211+
+ else if (ci->callstatus & CIST_FIN) { /* was it called as a finalizer? */
212+
+ *name = "__gc";
213+
+ return "metamethod"; /* report it as such */
214+
+ }
215+
+ else if (isLua(ci))
216+
+ return funcnamefromcode(L, ci_func(ci)->p, currentpc(ci), name);
217+
+ else
218+
+ return NULL;
219+
+}
220+
+
221+
/* }====================================================== */
222+
223+
224+
@@ -694,11 +702,15 @@ l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
225+
luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
226+
}
227+
228+
-
229+
+/*
230+
+** Raise an error for calling a non-callable object. Try to find a name
231+
+** for the object based on how it was called ('funcnamefromcall'); if it
232+
+** cannot get a name there, try 'varinfo'.
233+
+*/
234+
l_noret luaG_callerror (lua_State *L, const TValue *o) {
235+
CallInfo *ci = L->ci;
236+
const char *name = NULL; /* to avoid warnings */
237+
- const char *what = (isLua(ci)) ? funcnamefromcode(L, ci, &name) : NULL;
238+
+ const char *what = funcnamefromcall(L, ci, &name);
239+
if (what != NULL) {
240+
const char *t = luaT_objtypename(L, o);
241+
luaG_runerror(L, "%s '%s' is not callable (a %s value)", what, name, t);
242+
diff --git a/third-party/lua-5.4.3/src/lgc.c b/third-party/lua-5.4.3/src/lgc.c
243+
index b360eed..42a73d8 100644
244+
--- a/third-party/lua-5.4.3/src/lgc.c
245+
+++ b/third-party/lua-5.4.3/src/lgc.c
246+
@@ -906,18 +906,18 @@ static void GCTM (lua_State *L) {
247+
if (!notm(tm)) { /* is there a finalizer? */
248+
int status;
249+
lu_byte oldah = L->allowhook;
250+
- int running = g->gcrunning;
251+
+ int oldgcstp = g->gcstp;
252+
+ g->gcstp |= GCSTPGC; /* avoid GC steps */
253+
L->allowhook = 0; /* stop debug hooks during GC metamethod */
254+
- g->gcrunning = 0; /* avoid GC steps */
255+
setobj2s(L, L->top++, tm); /* push finalizer... */
256+
setobj2s(L, L->top++, &v); /* ... and its argument */
257+
L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
258+
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
259+
L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
260+
L->allowhook = oldah; /* restore hooks */
261+
- g->gcrunning = running; /* restore state */
262+
+ g->gcstp = oldgcstp; /* restore state */
263+
if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */
264+
- luaE_warnerror(L, "__gc metamethod");
265+
+ luaE_warnerror(L, "__gc");
266+
L->top--; /* pops error object */
267+
}
268+
}
269+
@@ -1011,7 +1011,8 @@ static void correctpointers (global_State *g, GCObject *o) {
270+
void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
271+
global_State *g = G(L);
272+
if (tofinalize(o) || /* obj. is already marked... */
273+
- gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */
274+
+ gfasttm(g, mt, TM_GC) == NULL || /* or has no finalizer... */
275+
+ (g->gcstp & GCSTPCLS)) /* or closing state? */
276+
return; /* nothing to be done */
277+
else { /* move 'o' to 'finobj' list */
278+
GCObject **p;
279+
@@ -1502,12 +1503,13 @@ static void deletelist (lua_State *L, GCObject *p, GCObject *limit) {
280+
*/
281+
void luaC_freeallobjects (lua_State *L) {
282+
global_State *g = G(L);
283+
+ g->gcstp = GCSTPCLS; /* no extra finalizers after here */
284+
luaC_changemode(L, KGC_INC);
285+
separatetobefnz(g, 1); /* separate all objects with finalizers */
286+
lua_assert(g->finobj == NULL);
287+
callallpendingfinalizers(L);
288+
deletelist(L, g->allgc, obj2gco(g->mainthread));
289+
- deletelist(L, g->finobj, NULL);
290+
+ lua_assert(g->finobj == NULL); /* no new finalizers */
291+
deletelist(L, g->fixedgc, NULL); /* collect fixed objects */
292+
lua_assert(g->strt.nuse == 0);
293+
}
294+
@@ -1647,6 +1649,7 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
295+
}
296+
297+
298+
+
299+
/*
300+
** Performs a basic incremental step. The debt and step size are
301+
** converted from bytes to "units of work"; then the function loops
302+
@@ -1678,7 +1681,7 @@ static void incstep (lua_State *L, global_State *g) {
303+
void luaC_step (lua_State *L) {
304+
global_State *g = G(L);
305+
lua_assert(!g->gcemergency);
306+
- if (g->gcrunning) { /* running? */
307+
+ if (gcrunning(g)) { /* running? */
308+
if(isdecGCmodegen(g))
309+
genstep(L, g);
310+
else
311+
diff --git a/third-party/lua-5.4.3/src/lgc.h b/third-party/lua-5.4.3/src/lgc.h
312+
index 073e2a4..4a12563 100644
313+
--- a/third-party/lua-5.4.3/src/lgc.h
314+
+++ b/third-party/lua-5.4.3/src/lgc.h
315+
@@ -148,6 +148,16 @@
316+
*/
317+
#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0)
318+
319+
+
320+
+/*
321+
+** Control when GC is running:
322+
+*/
323+
+#define GCSTPUSR 1 /* bit true when GC stopped by user */
324+
+#define GCSTPGC 2 /* bit true when GC stopped by itself */
325+
+#define GCSTPCLS 4 /* bit true when closing Lua state */
326+
+#define gcrunning(g) ((g)->gcstp == 0)
327+
+
328+
+
329+
/*
330+
** Does one step of collection when debt becomes positive. 'pre'/'pos'
331+
** allows some adjustments to be done only when needed. macro
332+
diff --git a/third-party/lua-5.4.3/src/llimits.h b/third-party/lua-5.4.3/src/llimits.h
333+
index 025f1c8..9a68a66 100644
334+
--- a/third-party/lua-5.4.3/src/llimits.h
335+
+++ b/third-party/lua-5.4.3/src/llimits.h
336+
@@ -347,7 +347,7 @@ typedef l_uint32 Instruction;
337+
#define condchangemem(L,pre,pos) ((void)0)
338+
#else
339+
#define condchangemem(L,pre,pos) \
340+
- { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } }
341+
+ { if (gcrunning(G(L))) { pre; luaC_fullgc(L, 0); pos; } }
342+
#endif
343+
344+
#endif
345+
diff --git a/third-party/lua-5.4.3/src/lstate.c b/third-party/lua-5.4.3/src/lstate.c
346+
index c5e3b43..6215ae8 100644
347+
--- a/third-party/lua-5.4.3/src/lstate.c
348+
+++ b/third-party/lua-5.4.3/src/lstate.c
349+
@@ -236,7 +236,7 @@ static void f_luaopen (lua_State *L, void *ud) {
350+
luaS_init(L);
351+
luaT_init(L);
352+
luaX_init(L);
353+
- g->gcrunning = 1; /* allow gc */
354+
+ g->gcstp = 0; /* allow gc */
355+
setnilvalue(&g->nilvalue); /* now state is complete */
356+
luai_userstateopen(L);
357+
}
358+
@@ -372,7 +372,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
359+
g->ud_warn = NULL;
360+
g->mainthread = L;
361+
g->seed = luai_makeseed(L);
362+
- g->gcrunning = 0; /* no GC while building state */
363+
+ g->gcstp = GCSTPGC; /* no GC while building state */
364+
g->strt.size = g->strt.nuse = 0;
365+
g->strt.hash = NULL;
366+
setnilvalue(&g->l_registry);
367+
diff --git a/third-party/lua-5.4.3/src/lstate.h b/third-party/lua-5.4.3/src/lstate.h
368+
index c1283bb..11f27fd 100644
369+
--- a/third-party/lua-5.4.3/src/lstate.h
370+
+++ b/third-party/lua-5.4.3/src/lstate.h
371+
@@ -209,7 +209,7 @@ typedef struct CallInfo {
372+
#define CIST_YPCALL (1<<4) /* doing a yieldable protected call */
373+
#define CIST_TAIL (1<<5) /* call was tail called */
374+
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
375+
-#define CIST_FIN (1<<7) /* call is running a finalizer */
376+
+#define CIST_FIN (1<<7) /* function "called" a finalizer */
377+
#define CIST_TRAN (1<<8) /* 'ci' has transfer information */
378+
#define CIST_CLSRET (1<<9) /* function is closing tbc variables */
379+
/* Bits 10-12 are used for CIST_RECST (see below) */
380+
@@ -263,7 +263,7 @@ typedef struct global_State {
381+
lu_byte gcstopem; /* stops emergency collections */
382+
lu_byte genminormul; /* control for minor generational collections */
383+
lu_byte genmajormul; /* control for major generational collections */
384+
- lu_byte gcrunning; /* true if GC is running */
385+
+ lu_byte gcstp; /* control whether GC is running */
386+
lu_byte gcemergency; /* true if this is an emergency collection */
387+
lu_byte gcpause; /* size of pause between successive GCs */
388+
lu_byte gcstepmul; /* GC "speed" */
389+
--
390+
2.45.2
391+

0 commit comments

Comments
 (0)