Compare commits

...

7 Commits

Author SHA1 Message Date
dan 0d7dfa9570 -Wall -Werror 2026-05-27 13:05:22 +01:00
dan ae1e109cd1 remove unused variable 2026-05-27 13:05:22 +01:00
dan cbdd65ecda remove useless check for fd > 0
we can't even be here if the fd is not valid
2026-05-27 13:05:22 +01:00
dan 0e03b0a763 print error if garbage received from client 2026-05-27 13:05:22 +01:00
dan 2fea793900 remove fork_lua return value check
as it dies on failure anyway
2026-05-27 13:05:22 +01:00
dan 1b018b3db4 check recvmsg return 2026-05-27 13:05:22 +01:00
dan adf7f542bb check for total fds passed inc. previous cmsgs 2026-05-27 13:05:22 +01:00
2 changed files with 33 additions and 17 deletions
+1
View File
@@ -1,5 +1,6 @@
default: luad luac
CFLAGS=-Wall -Werror
luad: LOADLIBES=-llua
install:
+32 -17
View File
@@ -19,16 +19,29 @@
#include <poll.h>
#include <arpa/inet.h>
#include <stdarg.h>
#include <stdnoreturn.h>
static int sigchild_fd = -1;
static void handle_sigchld(int num) {
if(sigchild_fd >= 0) {
write(sigchild_fd, "\n", 1);
(void) !write(sigchild_fd, "\n", 1);
}
}
#define die(...) error(EXIT_FAILURE, errno, __VA_ARGS__)
static void noreturn die(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
if(errno > 0) {
fprintf(stderr, "luad: %s: ", strerror(errno));
} else {
fprintf(stderr, "luad: ");
}
vfprintf(stderr, fmt, ap);
exit(1);
}
int open_socket(char * pathname) {
struct sockaddr_un addr;
@@ -66,7 +79,7 @@ int * fds_from_msg(struct msghdr *msg, int * peer_fds) {
if(cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
int passed_fd_count = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof (int);
if(i <= 3) {
if(i + passed_fd_count <= 3) {
memcpy(&peer_fds[i], CMSG_DATA(cmsg), passed_fd_count * sizeof(int));
} else {
@@ -94,7 +107,7 @@ int * fds_from_msg(struct msghdr *msg, int * peer_fds) {
}
}
int start_lua_child(lua_State *L,
void start_lua_child(lua_State *L,
char * command_line, int command_line_length,
int * fds) {
char * word = command_line;
@@ -104,7 +117,7 @@ int start_lua_child(lua_State *L,
fflush(stdout); fflush(stderr);
for(int i=0; i < 3; i++) {
if(fds[i] > 0) dup2(fds[i], i);
dup2(fds[i], i);
}
lua_newtable(L); /* arg */
@@ -118,12 +131,13 @@ int start_lua_child(lua_State *L,
lua_seti(L, -2, i++);
word = word_end + 1;
}
if(! pathname) {
die("no script name received from client");
}
lua_setglobal(L, "arg");
int status = luaL_dofile(L, pathname);
if (status) {
die("Lua error: %s", lua_tostring(L, -1));
} else {
return 0;
}
}
@@ -132,8 +146,8 @@ pid_t fork_lua(lua_State *L,
int * fds) {
pid_t pid = fork();
if(pid == 0) {
exit(start_lua_child(L, command_line, command_line_length,
fds));
start_lua_child(L, command_line, command_line_length, fds);
exit(0);
} else if(pid > 0) {
free(command_line);
return pid;
@@ -148,12 +162,10 @@ struct peer_entry {
struct sockaddr_un addr;
} peer_entries[500];
bool register_peer(pid_t pid, struct sockaddr_un *addr, int addrlen) {
if(addrlen > sizeof (struct sockaddr_un))
return false;
struct peer_entry *p = peer_entries;
int peer_entries_max = sizeof peer_entries / sizeof(peer_entries[0]);
for(int i=0; i < peer_entries_max; i++) {
@@ -208,7 +220,7 @@ int main(int argc, char **argv)
int socket = open_socket(socket_path);
struct sockaddr_un peer_addr;
socklen_t peer_addr_len;
char buf[1025];
struct iovec iov[1];
iov[0].iov_base = buf;
@@ -244,6 +256,8 @@ int main(int argc, char **argv)
if(pollfds[0].revents) {
if(find_peer(0)) {
int len = recvmsg(socket, &msg , 0);
if(len<=0) continue;
int peer_fds[3];
if(fds_from_msg(&msg, peer_fds)) {
char *argline = malloc(len);
@@ -253,9 +267,8 @@ int main(int argc, char **argv)
memmove(argline, buf, len);
pid_t child_pid = fork_lua(L, argline, len, peer_fds);
if(child_pid >= 0) {
register_peer(child_pid, &peer_addr, msg.msg_namelen);
}
register_peer(child_pid, &peer_addr, msg.msg_namelen);
/* close peer fds in parent */
close(peer_fds[0]);
close(peer_fds[1]);
@@ -268,8 +281,10 @@ int main(int argc, char **argv)
pid_t pid;
int wstatus;
read(pollfds[1].fd, buf, sizeof buf);
while((pid=waitpid(0, &wstatus, WNOHANG)) > 0) {
if(read(pollfds[1].fd, buf, sizeof buf) < 0)
continue;
while((pid = waitpid(0, &wstatus, WNOHANG)) > 0) {
struct peer_entry *peer = find_peer(pid);
if(peer) {
uint32_t ret = 0;