@@ -95,10 +95,18 @@ static int luv_update_time(lua_State* L) {
9595}
9696
9797static void luv_walk_cb (uv_handle_t * handle , void * arg ) {
98+ // This function expects to be passed a lua_State* with a callback function
99+ // at index 1 and the handle registry table at index 2. Libuv always calls
100+ // this function synchronously in uv_walk, so we can rely on the Lua state
101+ // from the caller of luv_walk instead of dispatching to the loop's main
102+ // thread both to avoid the xmove and to allow tracebacks to pass through
103+ // luv_walk.
104+
98105 lua_State * L = (lua_State * )arg ;
99106 luv_handle_t * data = (luv_handle_t * )handle -> data ;
100107
101- // Skip foreign handles (shared event loop)
108+ // check if registry[luv_handle_key][data] is not nil, which will only be true
109+ // if the data refers to a valid luv_handle_t* that is still in use.
102110 lua_rawgetp (L , 2 , data );
103111 if (lua_isnil (L , -1 )) {
104112 lua_pop (L , 1 );
@@ -112,6 +120,10 @@ static void luv_walk_cb(uv_handle_t* handle, void* arg) {
112120 luv_find_handle (L , data ); // Get the userdata
113121 uv_handle_t * * udata = (uv_handle_t * * )lua_touserdata (L , -1 );
114122 if (udata == NULL || * udata != handle ) {
123+ // This will only happen if someone forged a uv_handle_t* that points to a
124+ // uv_handle_t* created by luv. This is very unlikely, but if data does
125+ // happen to be unintentionally pointer-like we should avoid treating it
126+ // as valid.
115127 lua_pop (L , 2 ); // Pop the function and the userdata
116128 return ;
117129 }
@@ -120,9 +132,9 @@ static void luv_walk_cb(uv_handle_t* handle, void* arg) {
120132}
121133
122134static int luv_walk (lua_State * L ) {
123- luaL_checktype (L , 1 , LUA_TFUNCTION );
124- lua_settop (L , 1 );
125- lua_getfield (L , LUA_REGISTRYINDEX , luv_handle_key );
135+ luaL_checktype (L , 1 , LUA_TFUNCTION ); // Ensure index 1 is a function
136+ lua_settop (L , 1 ); // Remove any extra arguments
137+ lua_getfield (L , LUA_REGISTRYINDEX , luv_handle_key ); // Place the handle registry table at index 2
126138 uv_walk (luv_loop (L ), luv_walk_cb , L );
127139 return 0 ;
128140}
0 commit comments