aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-03-17 15:52:09 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-03-17 15:52:09 -0300
commitab859fe59b464a038a45552921cb2b23892343af (patch)
treec40223ce3f296c9d7e514b912931c093a8652c6a
parentc4b71b7ba0dee419b5bda1ec297eca8e42c9f1d2 (diff)
downloadlua-ab859fe59b464a038a45552921cb2b23892343af.tar.gz
lua-ab859fe59b464a038a45552921cb2b23892343af.tar.bz2
lua-ab859fe59b464a038a45552921cb2b23892343af.zip
Bug: Loading a corrupted binary file can segfault
The size of the list of upvalue names are stored separated from the size of the list of upvalues, but they share the same array.
-rw-r--r--ldump.c8
-rw-r--r--lundump.c2
-rw-r--r--testes/calls.lua14
3 files changed, 22 insertions, 2 deletions
diff --git a/ldump.c b/ldump.c
index f848b669..f231691b 100644
--- a/ldump.c
+++ b/ldump.c
@@ -10,6 +10,7 @@
10#include "lprefix.h" 10#include "lprefix.h"
11 11
12 12
13#include <limits.h>
13#include <stddef.h> 14#include <stddef.h>
14 15
15#include "lua.h" 16#include "lua.h"
@@ -55,8 +56,11 @@ static void dumpByte (DumpState *D, int y) {
55} 56}
56 57
57 58
58/* dumpInt Buff Size */ 59/*
59#define DIBS ((sizeof(size_t) * 8 / 7) + 1) 60** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6"
61** rounds up the division.)
62*/
63#define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7)
60 64
61static void dumpSize (DumpState *D, size_t x) { 65static void dumpSize (DumpState *D, size_t x) {
62 lu_byte buff[DIBS]; 66 lu_byte buff[DIBS];
diff --git a/lundump.c b/lundump.c
index aba93f82..02aed64f 100644
--- a/lundump.c
+++ b/lundump.c
@@ -248,6 +248,8 @@ static void loadDebug (LoadState *S, Proto *f) {
248 f->locvars[i].endpc = loadInt(S); 248 f->locvars[i].endpc = loadInt(S);
249 } 249 }
250 n = loadInt(S); 250 n = loadInt(S);
251 if (n != 0) /* does it have debug information? */
252 n = f->sizeupvalues; /* must be this many */
251 for (i = 0; i < n; i++) 253 for (i = 0; i < n; i++)
252 f->upvalues[i].name = loadStringN(S, f); 254 f->upvalues[i].name = loadStringN(S, f);
253} 255}
diff --git a/testes/calls.lua b/testes/calls.lua
index a1938584..2d562a24 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -342,6 +342,20 @@ do -- another bug (in 5.4.0)
342end 342end
343 343
344 344
345do -- another bug (since 5.2)
346 -- corrupted binary dump: list of upvalue names is larger than number
347 -- of upvalues, overflowing the array of upvalues.
348 local code =
349 "\x1b\x4c\x75\x61\x54\x00\x19\x93\x0d\x0a\x1a\x0a\x04\x08\x08\x78\x56\z
350 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x77\x40\x00\x86\x40\z
351 \x74\x65\x6d\x70\x81\x81\x01\x00\x02\x82\x48\x00\x02\x00\xc7\x00\x01\z
352 \x00\x80\x80\x80\x82\x00\x00\x80\x81\x82\x78\x80\x82\x81\x86\x40\x74\z
353 \x65\x6d\x70"
354
355 assert(load(code)) -- segfaults in previous versions
356end
357
358
345x = string.dump(load("x = 1; return x")) 359x = string.dump(load("x = 1; return x"))
346a = assert(load(read1(x), nil, "b")) 360a = assert(load(read1(x), nil, "b"))
347assert(a() == 1 and _G.x == 1) 361assert(a() == 1 and _G.x == 1)