aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-07-16 11:33:30 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-07-16 11:33:30 -0300
commitcd4de92762434e6ed0e6c207d56d365300396dd8 (patch)
tree9bc91eb85506b89d7cba0b859e2defce86aed7fc
parent6b45ccf4ed24dcfe437cf0159d6185119a2e8f95 (diff)
downloadlua-cd4de92762434e6ed0e6c207d56d365300396dd8.tar.gz
lua-cd4de92762434e6ed0e6c207d56d365300396dd8.tar.bz2
lua-cd4de92762434e6ed0e6c207d56d365300396dd8.zip
Maximum stack size may not fit in unsigned short
Therefore, fields ftransfer/ntransfer in lua_Debug must have type 'int'. (Maximum stack size must fit in an 'int'.) Also, this commit adds check that maximum stack size respects size_t for size in bytes.
-rw-r--r--ldo.c43
-rw-r--r--lstate.h4
-rw-r--r--lua.h4
-rw-r--r--luaconf.h8
-rw-r--r--manual/manual.of15
5 files changed, 46 insertions, 28 deletions
diff --git a/ldo.c b/ldo.c
index cd6dded6..34101ba3 100644
--- a/ldo.c
+++ b/ldo.c
@@ -171,6 +171,24 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
171** =================================================================== 171** ===================================================================
172*/ 172*/
173 173
174/* some stack space for error handling */
175#define STACKERRSPACE 200
176
177
178/* maximum stack size that respects size_t */
179#define MAXSTACK_BYSIZET ((MAX_SIZET / sizeof(StackValue)) - STACKERRSPACE)
180
181/*
182** Minimum between LUAI_MAXSTACK and MAXSTACK_BYSIZET
183** (Maximum size for the stack must respect size_t.)
184*/
185#define MAXSTACK cast_int(LUAI_MAXSTACK < MAXSTACK_BYSIZET \
186 ? LUAI_MAXSTACK : MAXSTACK_BYSIZET)
187
188
189/* stack size with extra space for error handling */
190#define ERRORSTACKSIZE (MAXSTACK + STACKERRSPACE)
191
174 192
175/* 193/*
176** Change all pointers to the stack into offsets. 194** Change all pointers to the stack into offsets.
@@ -208,9 +226,6 @@ static void correctstack (lua_State *L) {
208} 226}
209 227
210 228
211/* some space for error handling */
212#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
213
214/* 229/*
215** Reallocate the stack to a new size, correcting all pointers into it. 230** Reallocate the stack to a new size, correcting all pointers into it.
216** In ISO C, any pointer use after the pointer has been deallocated is 231** In ISO C, any pointer use after the pointer has been deallocated is
@@ -227,7 +242,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
227 int i; 242 int i;
228 StkId newstack; 243 StkId newstack;
229 int oldgcstop = G(L)->gcstopem; 244 int oldgcstop = G(L)->gcstopem;
230 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); 245 lua_assert(newsize <= MAXSTACK || newsize == ERRORSTACKSIZE);
231 relstack(L); /* change pointers to offsets */ 246 relstack(L); /* change pointers to offsets */
232 G(L)->gcstopem = 1; /* stop emergency collection */ 247 G(L)->gcstopem = 1; /* stop emergency collection */
233 newstack = luaM_reallocvector(L, L->stack.p, oldsize + EXTRA_STACK, 248 newstack = luaM_reallocvector(L, L->stack.p, oldsize + EXTRA_STACK,
@@ -254,7 +269,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
254*/ 269*/
255int luaD_growstack (lua_State *L, int n, int raiseerror) { 270int luaD_growstack (lua_State *L, int n, int raiseerror) {
256 int size = stacksize(L); 271 int size = stacksize(L);
257 if (l_unlikely(size > LUAI_MAXSTACK)) { 272 if (l_unlikely(size > MAXSTACK)) {
258 /* if stack is larger than maximum, thread is already using the 273 /* if stack is larger than maximum, thread is already using the
259 extra space reserved for errors, that is, thread is handling 274 extra space reserved for errors, that is, thread is handling
260 a stack error; cannot grow further than that. */ 275 a stack error; cannot grow further than that. */
@@ -263,14 +278,14 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
263 luaD_throw(L, LUA_ERRERR); /* error inside message handler */ 278 luaD_throw(L, LUA_ERRERR); /* error inside message handler */
264 return 0; /* if not 'raiseerror', just signal it */ 279 return 0; /* if not 'raiseerror', just signal it */
265 } 280 }
266 else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */ 281 else if (n < MAXSTACK) { /* avoids arithmetic overflows */
267 int newsize = 2 * size; /* tentative new size */ 282 int newsize = 2 * size; /* tentative new size */
268 int needed = cast_int(L->top.p - L->stack.p) + n; 283 int needed = cast_int(L->top.p - L->stack.p) + n;
269 if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ 284 if (newsize > MAXSTACK) /* cannot cross the limit */
270 newsize = LUAI_MAXSTACK; 285 newsize = MAXSTACK;
271 if (newsize < needed) /* but must respect what was asked for */ 286 if (newsize < needed) /* but must respect what was asked for */
272 newsize = needed; 287 newsize = needed;
273 if (l_likely(newsize <= LUAI_MAXSTACK)) 288 if (l_likely(newsize <= MAXSTACK))
274 return luaD_reallocstack(L, newsize, raiseerror); 289 return luaD_reallocstack(L, newsize, raiseerror);
275 } 290 }
276 /* else stack overflow */ 291 /* else stack overflow */
@@ -306,17 +321,17 @@ static int stackinuse (lua_State *L) {
306** to twice the current use. (So, the final stack size is at most 2/3 the 321** to twice the current use. (So, the final stack size is at most 2/3 the
307** previous size, and half of its entries are empty.) 322** previous size, and half of its entries are empty.)
308** As a particular case, if stack was handling a stack overflow and now 323** As a particular case, if stack was handling a stack overflow and now
309** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than 324** it is not, 'max' (limited by MAXSTACK) will be smaller than
310** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack 325** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack
311** will be reduced to a "regular" size. 326** will be reduced to a "regular" size.
312*/ 327*/
313void luaD_shrinkstack (lua_State *L) { 328void luaD_shrinkstack (lua_State *L) {
314 int inuse = stackinuse(L); 329 int inuse = stackinuse(L);
315 int max = (inuse > LUAI_MAXSTACK / 3) ? LUAI_MAXSTACK : inuse * 3; 330 int max = (inuse > MAXSTACK / 3) ? MAXSTACK : inuse * 3;
316 /* if thread is currently not handling a stack overflow and its 331 /* if thread is currently not handling a stack overflow and its
317 size is larger than maximum "reasonable" size, shrink it */ 332 size is larger than maximum "reasonable" size, shrink it */
318 if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) { 333 if (inuse <= MAXSTACK && stacksize(L) > max) {
319 int nsize = (inuse > LUAI_MAXSTACK / 2) ? LUAI_MAXSTACK : inuse * 2; 334 int nsize = (inuse > MAXSTACK / 2) ? MAXSTACK : inuse * 2;
320 luaD_reallocstack(L, nsize, 0); /* ok if that fails */ 335 luaD_reallocstack(L, nsize, 0); /* ok if that fails */
321 } 336 }
322 else /* don't change stack */ 337 else /* don't change stack */
@@ -408,7 +423,7 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
408 delta = ci->u.l.nextraargs + p->numparams + 1; 423 delta = ci->u.l.nextraargs + p->numparams + 1;
409 } 424 }
410 ci->func.p += delta; /* if vararg, back to virtual 'func' */ 425 ci->func.p += delta; /* if vararg, back to virtual 'func' */
411 ftransfer = cast(unsigned short, firstres - ci->func.p); 426 ftransfer = cast_int(firstres - ci->func.p);
412 luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */ 427 luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */
413 ci->func.p -= delta; 428 ci->func.p -= delta;
414 } 429 }
diff --git a/lstate.h b/lstate.h
index 6094016d..e5056abe 100644
--- a/lstate.h
+++ b/lstate.h
@@ -207,8 +207,8 @@ struct CallInfo {
207 int nyield; /* number of values yielded */ 207 int nyield; /* number of values yielded */
208 int nres; /* number of values returned */ 208 int nres; /* number of values returned */
209 struct { /* info about transferred values (for call/return hooks) */ 209 struct { /* info about transferred values (for call/return hooks) */
210 unsigned short ftransfer; /* offset of first value transferred */ 210 int ftransfer; /* offset of first value transferred */
211 unsigned short ntransfer; /* number of values transferred */ 211 int ntransfer; /* number of values transferred */
212 } transferinfo; 212 } transferinfo;
213 } u2; 213 } u2;
214 short nresults; /* expected number of results from this function */ 214 short nresults; /* expected number of results from this function */
diff --git a/lua.h b/lua.h
index 2f9d0abb..dcf49264 100644
--- a/lua.h
+++ b/lua.h
@@ -503,8 +503,8 @@ struct lua_Debug {
503 unsigned char nparams;/* (u) number of parameters */ 503 unsigned char nparams;/* (u) number of parameters */
504 char isvararg; /* (u) */ 504 char isvararg; /* (u) */
505 char istailcall; /* (t) */ 505 char istailcall; /* (t) */
506 unsigned short ftransfer; /* (r) index of first value transferred */ 506 int ftransfer; /* (r) index of first value transferred */
507 unsigned short ntransfer; /* (r) number of transferred values */ 507 int ntransfer; /* (r) number of transferred values */
508 char short_src[LUA_IDSIZE]; /* (S) */ 508 char short_src[LUA_IDSIZE]; /* (S) */
509 /* private part */ 509 /* private part */
510 struct CallInfo *i_ci; /* active function */ 510 struct CallInfo *i_ci; /* active function */
diff --git a/luaconf.h b/luaconf.h
index 65715c8b..80349acc 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -750,13 +750,13 @@
750@@ LUAI_MAXSTACK limits the size of the Lua stack. 750@@ LUAI_MAXSTACK limits the size of the Lua stack.
751** CHANGE it if you need a different limit. This limit is arbitrary; 751** CHANGE it if you need a different limit. This limit is arbitrary;
752** its only purpose is to stop Lua from consuming unlimited stack 752** its only purpose is to stop Lua from consuming unlimited stack
753** space (and to reserve some numbers for pseudo-indices). 753** space and to reserve some numbers for pseudo-indices.
754** (It must fit into max(size_t)/32 and max(int)/2.) 754** (It must fit into max(int)/2.)
755*/ 755*/
756#if LUAI_IS32INT 756#if 1000000 < (INT_MAX / 2)
757#define LUAI_MAXSTACK 1000000 757#define LUAI_MAXSTACK 1000000
758#else 758#else
759#define LUAI_MAXSTACK 15000 759#define LUAI_MAXSTACK (INT_MAX / 2u)
760#endif 760#endif
761 761
762 762
diff --git a/manual/manual.of b/manual/manual.of
index 56619afe..1069f644 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -4262,8 +4262,9 @@ you push the main function plus any arguments
4262onto the empty stack of the thread. 4262onto the empty stack of the thread.
4263then you call @Lid{lua_resume}, 4263then you call @Lid{lua_resume},
4264with @id{nargs} being the number of arguments. 4264with @id{nargs} being the number of arguments.
4265This call returns when the coroutine suspends or finishes its execution. 4265The function returns when the coroutine suspends,
4266When it returns, 4266finishes its execution, or raises an unprotected error.
4267When it returns without errors,
4267@id{*nresults} is updated and 4268@id{*nresults} is updated and
4268the top of the stack contains 4269the top of the stack contains
4269the @id{*nresults} values passed to @Lid{lua_yield} 4270the @id{*nresults} values passed to @Lid{lua_yield}
@@ -4274,9 +4275,11 @@ or returned by the body function.
4274without errors, 4275without errors,
4275or an error code in case of errors @see{statuscodes}. 4276or an error code in case of errors @see{statuscodes}.
4276In case of errors, 4277In case of errors,
4277the error object is on the top of the stack. 4278the error object is pushed on the top of the stack.
4279(In that case, @id{nresults} is not updated,
4280as its value would have to be 1 for the sole error object.)
4278 4281
4279To resume a coroutine, 4282To resume a suspended coroutine,
4280you remove the @id{*nresults} yielded values from its stack, 4283you remove the @id{*nresults} yielded values from its stack,
4281push the values to be passed as results from @id{yield}, 4284push the values to be passed as results from @id{yield},
4282and then call @Lid{lua_resume}. 4285and then call @Lid{lua_resume}.
@@ -4822,8 +4825,8 @@ typedef struct lua_Debug {
4822 unsigned char nparams; /* (u) number of parameters */ 4825 unsigned char nparams; /* (u) number of parameters */
4823 char isvararg; /* (u) */ 4826 char isvararg; /* (u) */
4824 char istailcall; /* (t) */ 4827 char istailcall; /* (t) */
4825 unsigned short ftransfer; /* (r) index of first value transferred */ 4828 int ftransfer; /* (r) index of first value transferred */
4826 unsigned short ntransfer; /* (r) number of transferred values */ 4829 int ntransfer; /* (r) number of transferred values */
4827 char short_src[LUA_IDSIZE]; /* (S) */ 4830 char short_src[LUA_IDSIZE]; /* (S) */
4828 /* private part */ 4831 /* private part */
4829 @rep{other fields} 4832 @rep{other fields}