Skip to content

Commit d2966af

Browse files
truemediansqueek502
authored andcommitted
assorted bug fixes and many memory corruption fixes
fix: fix pop(-1) stack corruption fix: fix many memory leaks and potential out-of-memory crashes remove schema, never been used fix: uninitialized memory access in parse_sockaddr fix: uv_interface_addresses can fail fix: interface indexes are already 1-based fix: prevent malloc(-1) fix: sparse_rawlen assumed the table was at index -2 fix: prevent infinite sleep nit: add missing copyright headers
1 parent 297bd33 commit d2966af

File tree

18 files changed

+177
-54
lines changed

18 files changed

+177
-54
lines changed

docs/docs.lua

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4529,21 +4529,19 @@ local doc = {
45294529
45304530
See [Constants][] for supported address `family` output values.
45314531
]],
4532-
returns = {
4533-
{
4534-
dict(
4535-
'string',
4536-
table({
4537-
{ 'ip', 'string' },
4538-
{ 'family', 'string' },
4539-
{ 'netmask', 'string' },
4540-
{ 'internal', 'boolean' },
4541-
{ 'mac', 'string' },
4542-
})
4543-
),
4544-
'addresses',
4545-
},
4546-
},
4532+
returns = ret_or_fail(
4533+
dict(
4534+
'string',
4535+
table({
4536+
{ 'ip', 'string' },
4537+
{ 'family', 'string' },
4538+
{ 'netmask', 'string' },
4539+
{ 'internal', 'boolean' },
4540+
{ 'mac', 'string' },
4541+
})
4542+
),
4543+
'addresses'
4544+
),
45474545
},
45484546
{
45494547
name = 'if_indextoname',

docs/docs.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/meta.lua

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/async.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ static int luv_new_async(lua_State* L) {
4444
}
4545
data = luv_setup_handle(L, ctx);
4646
data->extra = (luv_thread_arg_t*)malloc(sizeof(luv_thread_arg_t));
47+
if (!data->extra) {
48+
handle->data = data;
49+
uv_close((uv_handle_t*)handle, luv_handle_free);
50+
return luaL_error(L, "Failed to allocate async args");
51+
}
4752
data->extra_gc = free;
4853
memset(data->extra, 0, sizeof(luv_thread_arg_t));
4954
handle->data = data;

src/fs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,8 @@ static int luv_fs_read(lua_State* L) {
543543
offset = luaL_optinteger(L, 3, offset);
544544
ref = luv_check_continuation(L, 4);
545545
}
546+
if (len < 0)
547+
return luaL_error(L, "Length must be non-negative");
546548
data = (char*)malloc(len);
547549
if (!data) {
548550
luaL_unref(L, LUA_REGISTRYINDEX, ref);

src/handle.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@
1818

1919
static void* luv_newuserdata(lua_State* L, size_t sz) {
2020
void* handle = malloc(sz);
21-
if (handle) {
22-
*(void**)lua_newuserdata(L, sizeof(void*)) = handle;
21+
if (!handle) {
22+
luaL_error(L, "out of memory");
23+
return NULL; // unreachable
2324
}
25+
26+
*(void**)lua_newuserdata(L, sizeof(void*)) = handle;
2427
return handle;
2528
}
2629

src/lhandle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,6 @@ typedef struct {
5050
luv_handle_extra_gc extra_gc;
5151
} luv_handle_t;
5252

53+
static void luv_handle_free(uv_handle_t* handle);
54+
5355
#endif

src/luv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ typedef int (*luv_CFcpcall) (lua_State* L, lua_CFunction func, void* ud, int fla
9393
/* Default implementation of event callback */
9494
LUALIB_API int luv_cfpcall(lua_State* L, int nargs, int nresult, int flags);
9595

96-
/* Default implementation of thread entory function */
96+
/* Default implementation of thread entry function */
9797
LUALIB_API int luv_cfcpcall(lua_State* L, lua_CFunction func, void* ud, int flags);
9898

9999
typedef struct {

src/misc.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,26 @@ static uv_buf_t* luv_prep_bufs(lua_State* L, int index, size_t *count, int **ref
6565
}
6666
*count = cnt;
6767
bufs = (uv_buf_t*)malloc(sizeof(uv_buf_t) * *count);
68+
if (!bufs) luaL_error(L, "Failed to allocate buffer array");
6869
int *refs_array = NULL;
69-
if (refs)
70+
if (refs) {
7071
refs_array = (int*)malloc(sizeof(int) * (*count + 1));
72+
if (!refs_array) {
73+
free(bufs);
74+
luaL_error(L, "Failed to allocate refs array");
75+
}
76+
}
7177
for (i = 0; i < *count; ++i) {
7278
lua_rawgeti(L, index, i + 1);
7379
if (!lua_isstring(L, -1)) {
80+
/* free already-accumulated refs and heap allocations before throwing */
81+
if (refs_array) {
82+
size_t j;
83+
for (j = 0; j < i; ++j)
84+
luaL_unref(L, LUA_REGISTRYINDEX, refs_array[j]);
85+
free(refs_array);
86+
}
87+
free(bufs);
7488
luaL_argerror(L, index, lua_pushfstring(L, "expected table of strings, found %s in the table", luaL_typename(L, -1)));
7589
return NULL;
7690
}
@@ -105,6 +119,7 @@ static uv_buf_t* luv_check_bufs(lua_State* L, int index, size_t* count, luv_req_
105119
else if (lua_isstring(L, index)) {
106120
*count = 1;
107121
bufs = (uv_buf_t*)malloc(sizeof(uv_buf_t));
122+
if (!bufs) luaL_error(L, "Failed to allocate buffer");
108123
luv_prep_buf(L, index, bufs);
109124
lua_pushvalue(L, index);
110125
req_data->data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
@@ -125,6 +140,7 @@ static uv_buf_t* luv_check_bufs_noref(lua_State* L, int index, size_t* count) {
125140
else if (lua_isstring(L, index)) {
126141
*count = 1;
127142
bufs = (uv_buf_t*)malloc(sizeof(uv_buf_t));
143+
if (!bufs) luaL_error(L, "Failed to allocate buffer");
128144
luv_prep_buf(L, index, bufs);
129145
}
130146
else {
@@ -290,7 +306,8 @@ static int luv_interface_addresses(lua_State* L) {
290306
char ip[INET6_ADDRSTRLEN];
291307
char netmask[INET6_ADDRSTRLEN];
292308

293-
uv_interface_addresses(&interfaces, &count);
309+
int ret = uv_interface_addresses(&interfaces, &count);
310+
if (ret < 0) return luv_error(L, ret);
294311

295312
lua_newtable(L);
296313

@@ -494,7 +511,14 @@ static int luv_os_getenv(lua_State* L) {
494511
const char* name = luaL_checkstring(L, 1);
495512
size_t size = luaL_optinteger(L, 2, LUAL_BUFFERSIZE);
496513
char *buff = malloc(size);
514+
if (!buff) return luaL_error(L, "Failed to allocate env buffer");
497515
int ret = uv_os_getenv(name, buff, &size);
516+
if (ret == UV_ENOBUFS) {
517+
/* size has been updated with the required length; reallocate and retry */
518+
buff = realloc(buff, size);
519+
if (!buff) return luaL_error(L, "Failed to allocate env buffer");
520+
ret = uv_os_getenv(name, buff, &size);
521+
}
498522
if (ret == 0) {
499523
lua_pushlstring(L, buff, size);
500524
ret = 1;
@@ -550,7 +574,7 @@ static int luv_if_indextoname(lua_State* L) {
550574
size_t scoped_addr_len = sizeof(scoped_addr);
551575
unsigned int ifindex = (unsigned int)luaL_checkinteger(L, 1);
552576

553-
int ret = uv_if_indextoname(ifindex - 1, scoped_addr, &scoped_addr_len);
577+
int ret = uv_if_indextoname(ifindex, scoped_addr, &scoped_addr_len);
554578
if (ret == 0) {
555579
lua_pushlstring(L, scoped_addr, scoped_addr_len);
556580
ret = 1;
@@ -565,7 +589,7 @@ static int luv_if_indextoiid(lua_State* L) {
565589
size_t interface_id_len = sizeof(interface_id);
566590
unsigned int ifindex = (unsigned int)luaL_checkinteger(L, 1);
567591

568-
int ret = uv_if_indextoiid(ifindex - 1, interface_id, &interface_id_len);
592+
int ret = uv_if_indextoiid(ifindex, interface_id, &interface_id_len);
569593
if (ret == 0) {
570594
lua_pushlstring(L, interface_id, interface_id_len);
571595
ret = 1;
@@ -683,14 +707,17 @@ static int luv_os_environ(lua_State* L) {
683707
#endif
684708

685709
static int luv_sleep(lua_State* L) {
686-
unsigned int msec = luaL_checkinteger(L, 1);
710+
int msec = luaL_checkinteger(L, 1);
711+
if (msec < 0)
712+
msec = 0;
713+
687714
#if LUV_UV_VERSION_GEQ(1, 34, 0)
688-
uv_sleep(msec);
715+
uv_sleep((unsigned int)msec);
689716
#else
690717
#ifdef _WIN32
691-
Sleep(msec);
718+
Sleep((unsigned int)msec);
692719
#else
693-
usleep(msec * 1000);
720+
usleep((unsigned int)msec * 1000);
694721
#endif
695722
#endif
696723
return 0;
@@ -824,7 +851,7 @@ static int luv_utf16_to_wtf8(lua_State *L) {
824851
sz = uv_utf16_length_as_wtf8(utf16, utf16_len);
825852
/* The wtf8_ptr must contain an extra space for an extra NUL after the result */
826853
wtf8 = malloc(sz + 1);
827-
if (wtf8 == NULL) return luaL_error(L, "failed to allocate %zu bytes", sz + 1);
854+
if (wtf8 == NULL) return luaL_error(L, "out of memory");
828855
/* Note: On success, *sz will not be modified */
829856
ret = uv_utf16_to_wtf8(utf16, utf16_len, &wtf8, &sz);
830857
if (ret == 0) {
@@ -852,7 +879,7 @@ static int luv_wtf8_to_utf16(lua_State *L) {
852879
const char* wtf8 = luaL_checklstring(L, 1, &sz);
853880
ssize_t ssz = uv_wtf8_length_as_utf16(wtf8);
854881
utf16 = malloc(ssz * 2);
855-
if (utf16 == NULL) return luaL_error(L, "failed to allocate %zu bytes", ssz * 2);
882+
if (utf16 == NULL) return luaL_error(L, "out of memory");
856883
uv_wtf8_to_utf16(wtf8, utf16, ssz);
857884
/* The returned string includes a NUL terminator, but we use Lua style string */
858885
lua_pushlstring(L, (const char*)utf16, (ssz-1) * 2);

src/private.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
* Copyright 2014 The Luvit Authors. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
117
#ifndef LUV_PRIVATE_H
218
#define LUV_PRIVATE_H
319

0 commit comments

Comments
 (0)