iotjs icon indicating copy to clipboard operation
iotjs copied to clipboard

Invalid address string processing in UDP module Bind function

Open pmarcinkiew opened this issue 8 years ago • 0 comments

IP address is passed from iotjs_string to uv_ipv4_address using iotjs_string_data function:

https://github.com/Samsung/iotjs/blob/master/src/modules/iotjs_module_udp.c#L155

The iotjs_string doesn't contain null terminated string and iotjs_string_data just returns buffer to this unterminated string. The function uv_ipv4_address calls several functions inside with just snprintf used in the bottom to copy address.

The simple grep for uv_ and iotjs_string_data generates list of 8 more suspicious places, which contains similar bug.

piotr@bdell:~/src/iotjs/src$ grep -Rn uv_ | grep iotjs_string_data
modules/iotjs_module_tcp.c:275:  int err = uv_ip4_addr(iotjs_string_data(&address), port, &addr);
modules/iotjs_module_tcp.c:327:  int err = uv_ip4_addr(iotjs_string_data(&address), port, &addr);
modules/iotjs_module_udp.c:156:      uv_ip4_addr(iotjs_string_data(&address), port, (sockaddr_in*)(&addr));
modules/iotjs_module_udp.c:310:      uv_ip4_addr(iotjs_string_data(&address), port, (sockaddr_in*)(&addr));
modules/iotjs_module_process.c:160:  int err = uv_chdir(iotjs_string_data(&path));
modules/iotjs_module_udp.c~:155:      uv_ip4_addr(iotjs_string_data(&address), port, (sockaddr_in*)(&addr));
modules/iotjs_module_udp.c~:307:      uv_ip4_addr(iotjs_string_data(&address), port, (sockaddr_in*)(&addr));

This bug was introduced here:

https://github.com/Samsung/iotjs/pull/636

Please find debugging log for TizenRT with this issue:

(gdb) c
Continuing.

Breakpoint 11, uv_ip4_addr (ip=0x2086cb0 "127.0.0.1\"#32\"); ", port=41234, addr=0x209f5f8) at /home/piotr/src/iotjs/deps/libtuv/src/uv-common.c:136
136       memset(addr, 0, sizeof(*addr));
(gdb) l
131     }
132     #undef UV_STRERROR_GEN
133
134
135     int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
136       memset(addr, 0, sizeof(*addr));
137       addr->sin_family = AF_INET;
138       addr->sin_port = htons(port);
139       return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr));

Testing JavaScript:

 16 var assert = require('assert');                                                                                                                                          
 17 var dgram = require('dgram');                                                                                                                                            
 18                                                                                                                                                                          
 19 var port = 41234;                                                                                                                                                        
 20 var msg = 'Hello IoT.js';                                                                                                                                                
 21 var addr = '127.0.0.1'; // Change to your ip address                                                                                                                     
 22 var client = dgram.createSocket('udp4');                                                                                                                                 
 23                                                                                                                                                                          
 24 client.bind({port:port, address: addr}, function() {                                                                                                                     
 25     console.log("success");                                                                                                                                              
 26 }); 

pmarcinkiew avatar Sep 04 '17 20:09 pmarcinkiew