diff options
author | antirez <antirez@gmail.com> | 2018-05-15 13:13:49 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2018-06-13 12:40:33 +0200 |
commit | e89086e09a38cc6713bcd4b9c29abf92cf393936 (patch) | |
tree | 02f3278babdc0e521d5fc02d6534894cc31b9a12 /deps/lua | |
parent | 5ccb6f7a791bf3490357b00a898885759d98bab0 (diff) | |
download | redis-e89086e09a38cc6713bcd4b9c29abf92cf393936.tar.gz |
Security: fix Lua struct package offset handling.
After the first fix to the struct package I found another similar
problem, which is fixed by this patch. It could be reproduced easily by
running the following script:
return struct.unpack('f', "xxxxxxxxxxxxx",-3)
The above will access bytes before the 'data' pointer.
Diffstat (limited to 'deps/lua')
-rw-r--r-- | deps/lua/src/lua_struct.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/deps/lua/src/lua_struct.c b/deps/lua/src/lua_struct.c index b03a002da..4d5f027b8 100644 --- a/deps/lua/src/lua_struct.c +++ b/deps/lua/src/lua_struct.c @@ -293,14 +293,18 @@ static int b_unpack (lua_State *L) { const char *fmt = luaL_checkstring(L, 1); size_t ld; const char *data = luaL_checklstring(L, 2, &ld); - size_t pos = luaL_optinteger(L, 3, 1) - 1; + size_t pos = luaL_optinteger(L, 3, 1); + luaL_argcheck(L, pos > 0, 3, "offset must be 1 or greater"); + pos--; /* Lua indexes are 1-based, but here we want 0-based for C + * pointer math. */ int n = 0; /* number of results */ defaultoptions(&h); while (*fmt) { int opt = *fmt++; size_t size = optsize(L, opt, &fmt); pos += gettoalign(pos, &h, opt, size); - luaL_argcheck(L, pos+size <= ld, 2, "data string too short"); + luaL_argcheck(L, size <= ld && pos <= ld - size, + 2, "data string too short"); /* stack space for item + next position */ luaL_checkstack(L, 2, "too many results"); switch (opt) { |