Skip to content

Commit

Permalink
lkl tools: check if host calls are initialized
Browse files Browse the repository at this point in the history
The host calls may not be initialized from the constructor calls if
another constructor calls one of the hooked functions. Manually check
for that to avoid this issue.

Reported-by: Hajime Tazaki <thehajime@gmail.com>
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
  • Loading branch information
Octavian Purdila committed Jan 10, 2016
1 parent 3e2c13b commit c9b823f
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion tools/lkl/lib/hijack/hijack.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ static host_call host_calls[__lkl__NR_syscalls];
{ \
long p[6] = {p1, p2, p3, p4, p5, p6 }; \
\
if (!host_calls[__lkl__NR_##name]) \
host_calls[__lkl__NR_##name] = resolve_sym(#name); \
if (!is_lklfd(p1)) \
return host_calls[__lkl__NR_##name](p1, p2, p3, \
p4, p5, p6); \
Expand Down Expand Up @@ -96,6 +98,9 @@ static host_call host_calls[__lkl__NR_syscalls];
asm(".global " #name); \
asm(".set " #name "," #name "_hook"); \

#define CHECK_HOST_CALL(name) \
if (!host_##name) \
host_##name = resolve_sym(#name)

static int lkl_call(int nr, int args, ...)
{
Expand Down Expand Up @@ -136,6 +141,7 @@ HOST_CALL(setsockopt);
int setsockopt(int fd, int level, int optname, const void *optval,
socklen_t optlen)
{
CHECK_HOST_CALL(setsockopt);
if (!is_lklfd(fd))
return host_setsockopt(fd, level, optname, optval, optlen);
return lkl_call(__lkl__NR_setsockopt, 5, fd, lkl_solevel_xlate(level),
Expand All @@ -145,6 +151,7 @@ int setsockopt(int fd, int level, int optname, const void *optval,
HOST_CALL(getsockopt);
int getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
{
CHECK_HOST_CALL(getsockopt);
if (!is_lklfd(fd))
return host_setsockopt(fd, level, optname, optval, optlen);
return lkl_call(__lkl__NR_getsockopt, 5, fd, lkl_solevel_xlate(level),
Expand All @@ -154,6 +161,7 @@ int getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
HOST_CALL(socket);
int socket(int domain, int type, int protocol)
{
CHECK_HOST_CALL(socket);
if (domain == AF_UNIX)
return host_socket(domain, type, protocol);

Expand All @@ -170,6 +178,8 @@ int ioctl(int fd, unsigned long req, ...)
arg = va_arg(vl, long);
va_end(vl);

CHECK_HOST_CALL(ioctl);

if (!is_lklfd(fd))
return host_ioctl(fd, req, arg);
return lkl_call(__lkl__NR_fcntl, 3, fd, lkl_ioctl_req_xlate(req), arg);
Expand All @@ -186,6 +196,8 @@ int fcntl(int fd, int cmd, ...)
arg = va_arg(vl, long);
va_end(vl);

CHECK_HOST_CALL(fcntl);

if (!is_lklfd(fd))
return host_fcntl(fd, cmd, arg);
return lkl_call(__lkl__NR_fcntl, 3, fd, lkl_fcntl_cmd_xlate(cmd), arg);
Expand All @@ -196,6 +208,8 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
unsigned int i, lklfds = 0, hostfds = 0;

CHECK_HOST_CALL(poll);

for (i = 0; i < nfds; i++) {
if (is_lklfd(fds[i].fd))
lklfds = 1;
Expand All @@ -221,6 +235,8 @@ int select(int nfds, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
{
int fd, hostfds = 0, lklfds = 0;

CHECK_HOST_CALL(select);

for (fd = 0; fd < nfds; fd++) {
if (r != 0 && FD_ISSET(fd, r)) {
if (is_lklfd(fd))
Expand Down Expand Up @@ -257,10 +273,11 @@ HOOK_CALL(epoll_create)
HOST_CALL(epoll_ctl);
int epoll_ctl(int epollfd, int op, int fd, struct epoll_event *event)
{
CHECK_HOST_CALL(epoll_ctl);

if (is_lklfd(epollfd) != is_lklfd(fd))
return lkl_set_errno(LKL_EOPNOTSUPP);


if (!is_lklfd(epollfd))
return host_epoll_ctl(epollfd, op, fd, event);

Expand Down

0 comments on commit c9b823f

Please sign in to comment.