diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-03-17 15:52:09 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-03-17 15:52:09 -0300 |
| commit | ab859fe59b464a038a45552921cb2b23892343af (patch) | |
| tree | c40223ce3f296c9d7e514b912931c093a8652c6a | |
| parent | c4b71b7ba0dee419b5bda1ec297eca8e42c9f1d2 (diff) | |
| download | lua-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.c | 8 | ||||
| -rw-r--r-- | lundump.c | 2 | ||||
| -rw-r--r-- | testes/calls.lua | 14 |
3 files changed, 22 insertions, 2 deletions
| @@ -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 | ||
| 61 | static void dumpSize (DumpState *D, size_t x) { | 65 | static void dumpSize (DumpState *D, size_t x) { |
| 62 | lu_byte buff[DIBS]; | 66 | lu_byte buff[DIBS]; |
| @@ -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) | |||
| 342 | end | 342 | end |
| 343 | 343 | ||
| 344 | 344 | ||
| 345 | do -- 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 | ||
| 356 | end | ||
| 357 | |||
| 358 | |||
| 345 | x = string.dump(load("x = 1; return x")) | 359 | x = string.dump(load("x = 1; return x")) |
| 346 | a = assert(load(read1(x), nil, "b")) | 360 | a = assert(load(read1(x), nil, "b")) |
| 347 | assert(a() == 1 and _G.x == 1) | 361 | assert(a() == 1 and _G.x == 1) |
