From 10e378394861b8261eac4366658dad069aa12f63 Mon Sep 17 00:00:00 2001 From: Yiheng Cao <65160922+Crispy-fried-chicken@users.noreply.github.com> Date: Tue, 6 Feb 2024 08:27:00 +0800 Subject: [PATCH] Fix potential integer overflow in getnum and fix the negation overflow in lua (#3634) --- components/lua/lua-5.3/ldebug.c | 7 ++++--- components/modules/struct.c | 10 ++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/components/lua/lua-5.3/ldebug.c b/components/lua/lua-5.3/ldebug.c index 7f02f78c36..aee12c3f29 100644 --- a/components/lua/lua-5.3/ldebug.c +++ b/components/lua/lua-5.3/ldebug.c @@ -132,10 +132,11 @@ static const char *upvalname (Proto *p, int uv) { static const char *findvararg (CallInfo *ci, int n, StkId *pos) { int nparams = getnumparams(clLvalue(ci->func)->p); - if (n >= cast_int(ci->u.l.base - ci->func) - nparams) + int nvararg = cast_int(ci->u.l.base - ci->func) - nparams; + if (n <= -nvararg) return NULL; /* no such vararg */ else { - *pos = ci->func + nparams + n; + *pos = ci->func + nparams - n; return "(*vararg)"; /* generic name for any vararg */ } } @@ -147,7 +148,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, StkId base; if (isLua(ci)) { if (n < 0) /* access to vararg values? */ - return findvararg(ci, -n, pos); + return findvararg(ci, n, pos); else { base = ci->u.l.base; name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); diff --git a/components/modules/struct.c b/components/modules/struct.c index 7a6ebb7cfa..0cf7414c5b 100644 --- a/components/modules/struct.c +++ b/components/modules/struct.c @@ -93,12 +93,14 @@ typedef struct Header { } Header; -static int getnum (const char **fmt, int df) { +static int getnum (lua_State *L, const char **fmt, int df) { if (!isdigit((unsigned char)**fmt)) /* no number? */ return df; /* return default value */ else { int a = 0; do { + if (a > (INT_MAX / 10) || a * 10 > (INT_MAX - (**fmt - '0'))) + luaL_error(L, "integral size overflow"); a = a*10 + *((*fmt)++) - '0'; } while (isdigit((unsigned char)**fmt)); return a; @@ -121,9 +123,9 @@ static size_t optsize (lua_State *L, char opt, const char **fmt) { case 'd': return sizeof(double); #endif case 'x': return 1; - case 'c': return getnum(fmt, 1); + case 'c': return getnum(L, fmt, 1); case 'i': case 'I': { - int sz = getnum(fmt, sizeof(int)); + int sz = getnum(L, fmt, sizeof(int)); if (sz > MAXINTSIZE) luaL_error(L, "integral size %d is larger than limit of %d", sz, MAXINTSIZE); @@ -156,7 +158,7 @@ static void controloptions (lua_State *L, int opt, const char **fmt, case '>': h->endian = BIG; return; case '<': h->endian = LITTLE; return; case '!': { - int a = getnum(fmt, MAXALIGN); + int a = getnum(L, fmt, MAXALIGN); if (!isp2(a)) luaL_error(L, "alignment %d is not a power of 2", a); h->align = a;