lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi.

I analyzed the use of CallInfo func field,
then I figured out that the field is used as either CClosure or LClosure.

First, at the entry of the VM dispatch loop (Lua 5.4.3),
the CallInfo func field is cast as LClosure as follows:
  ```c
  void luaV_execute (lua_State *L, CallInfo *ci) {
    ...
    startfunc:
      trap = L->hookmask;
    returning:  /* trap already set */
      cl = clLvalue(s2v(ci->func));
  ```

However, it is hard to verify the safety of this cast,
because of the dynamic assignments to ci->func at insn OP_TAILCALL, OP_RETURN as follows:
  ```c
  vmcase(OP_TAILCALL) {
    ci->func -= delta;  /* restore 'func' (if vararg) */
  vmcase(OP_RETURN) {
    int nparams1 = GETARG_C(i);
    if (nparams1)  /* vararg function? */
      ci->func -= ci->u.l.nextraargs + nparams1;
  ```

Furthermore, the function index2value (./src/lapi.c) assumes that
ci->func is type of either CClosure or LClosure implicitly as follows:
  ```c
  if (ttislcf(s2v(ci->func)))  /* light C function? */
    return &G(L)->nilvalue;  /* it has no upvalues */
  else {
    CClosure *func = clCvalue(s2v(ci->func));
  ```

I couldn't affirm that these CallInfo func field usages are all safe.

Hence, I write a small patch on the entry of the VM dispatch loop (Lua 5.4.3).
This is because this is the most important checking in Lua execution.
I'm not expert in Lua core development,
so this too sloppy error handling may not be appropriate.
Please handle this patch as Proof-of-Concept.

If this patch seems to be effective,
I will write another patch to enforce type checking elsewhere (e.g., index2value).
Please tell me if you have any opinion about this patch.

===
diff --git a/src/lvm.c b/src/lvm.c
index c9729bc..825c234 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1138,6 +1138,9 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
  startfunc:
   trap = L->hookmask;
  returning:  /* trap already set */
+  if (!ttisLclosure(s2v(ci->func))) {
+    return;
+  }
   cl = clLvalue(s2v(ci->func));
   k = cl->p->k;
   pc = ci->u.l.savedpc;
===

Regards,

。:+* ゜ ゜゜ *+:。:+* ゜ ゜゜ *+:。:+* ゜ ゜゜ *+:。
Tatsuhiro Aoshima
NTT Secure Platform Laboratories
Phone: +81 422 59 3261 [JPN: (0422) 59 3261]