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.
Diffstat (limited to '')
-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)