[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Crashy bugette in LuaSocket?
- From: Duck <duck@...>
- Date: Tue, 12 Jun 2007 08:19:14 +1000 (EST)
I was using a lua interpreter + LuaSocket as a sort of "rich man's" netcat
over the weekend. Doing various socket stuff repetitiously by hand meant I
occasionally got things in the wrong order, like this...
s = coresock.tcp()
s:connect("lua.org",80)
s:close()
m,e = s:receive(1024) -- same with receiving "*l"
= m,e
nil closed
...or like this...
s = coresock.tcp()
s:connect("lua.org",80)
s:close()
m,e = s:receive("*a")
Segmentation fault
user@my.example:~$
A very quick glance in the debugger suggests that the receive() method is
called, into recvall() and into this:
static int buffer_get(p_buffer buf, const char **data, size_t *count) {
int err = IO_DONE;
p_io io = buf->io;
p_timeout tm = buf->tm;
if (buffer_isempty(buf)) {
size_t got;
err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm);
buf->first = 0;
buf->last = got;
}
*count = buf->last - buf->first;
*data = buf->data + buf->first;
return err;
}
In my build (debug and release), "got" is not initialised to zero and
since io->recv returns immediately with IO_CLOSED withit writing into
&got, it ends up with the value [large positive int], so on return to:
static int recvall(p_buffer buf, luaL_Buffer *b) {
int err = IO_DONE;
while (err == IO_DONE) {
const char *data; size_t count;
err = buffer_get(buf, &data, &count);
luaL_addlstring(b, data, count);
buffer_skip(buf, count);
}
if (err == IO_CLOSED) return IO_DONE;
else return err;
}
the luaL_addlstring() causes a buffer overflow.
Changing "size_t got" to "size_t *got = 0" prevents this problem, but
introduces another: when calling recvall() (which receive("*a") does but
receive(1024) and receive("*l") do not), the error IO_CLOSED is mapped
back to IO_DONE, so that the in above Lua code, you can't ever check, from
the return values of s:receive("*a"), that the socket was closed when you
tried to read from it -- is this correct behaviour for "*a" ?