jmckaskill / luaffi

Standalone FFI library for calling C functions from lua. Compatible with the luajit FFI interface.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

segfault

justincormack opened this issue · comments

running lua test.lua on the head version of ljsyscall now gives

lua: ffi.c:708: get_member: Assertion `ct->is_variable_struct && ct->variable_size_known && mt->is_array' failed.
and segfaults

Will make a reduced test case, its after the recvmsg call, passing credentials, not the simplest interface...

I get the following:

james@hawea ~/c/ljsyscall $ git describe                                                                                                              master 
v0.1-147-g7891081
james@hawea ~/c/ljsyscall $ lua test.lua                                                                                                              master 
hawea Linux 2.6.37-2-amd64 #1 SMP Sun Feb 27 10:12:22 UTC 2011
lua: test.lua:227: Can't set a pointer member to a struct that's about to be freed
stack traceback:
    [C]: in function 'cast'
    test.lua:227: in main chunk
    [C]: ?

Or do you have a more recent version somewhere else then on github?

Oh I see what my error is about. The S.cast("char_", 1). It tried to cast 1 to a char_ and failed and so fell back on casting {1} to char* which failed due to the temp array.

Aha, now I get it. A fix to luaffi for the temp array, fix to ljsyscall for the ffi.cast('long', ..) != -1 and update luabitop to latest version (my version was missing bswap).

Here is a smaller test case

local S = require "syscall"

local sv = assert(S.socketpair("unix", "stream"))

assert(sv[2]:setsockopt("socket", "passcred", true)) -- enable receive creds
local so = assert(sv[2]:getsockopt(S.SOL_SOCKET, S.SO_PASSCRED))
assert(so == 1, "getsockopt should have updated value")

assert(sv[1]:sendmsg()) -- sends single byte, which is enough to send credentials
local r = assert(sv[2]:recvmsg())
assert(r.pid == S.getpid(), "expect to get my pid from sending credentials")

It segfaults on recvmsg

it is failing on

local cred = t.ucred()
ffi.copy(cred, cmsg.cmsg_data, ffi.sizeof(t.ucred))

This code is not very nice, so may rewrite it but does seem to be a bug.

Ah I see whats up,

struct cmsghdr {
  size_t cmsg_len;
  int cmsg_level;
  int cmsg_type;
  unsigned char cmsg_data[?];
};

it doesnt know what size the cmsg struct is, because of the variable length array, so it doesnt feel inclined to cast it.

The error is that it even let you create a cmsghdr without specifying the variable size.

Have fixed this in ljsyscall now. I am fine not using variable length arrays at end of struct really, probably not a priority to fix. There are some other uses, but may be ok if not casting them.

It is not created, it is cast to a cmsghdr I think, thats the issue. Which is I think legal. Removed it anyway...

On Mon, Jun 4, 2012 at 10:49 PM, Justin Cormack <
reply@reply.github.com

wrote:

Removed it anyway...

Fixed it anyway...