commit a820bbf9330bc46238b6d284a90e8ac88f9691de
parent 7e123822485df1e01abf2a698f10b21540f4c24e
Author: Daniel Barlow <dan@telent.net>
Date: Tue, 19 May 2026 21:50:02 +0100
verify we get exactly 3 fds from client
Diffstat:
| M | luad.c | | | 31 | +++++++++++++++++++++++++++++-- |
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/luad.c b/luad.c
@@ -55,16 +55,43 @@ int * fds_from_msg(struct msghdr *msg, int * peer_fds) {
// * we expect three fds
// * if we get some number other than three, we should
// close all of them and return NULL because someone is up to no good
+ int i = 0;
+ peer_fds[0] = -1;
+ peer_fds[1] = -1;
+ peer_fds[2] = -1;
for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(msg);
cmsg != NULL;
cmsg = CMSG_NXTHDR(msg, cmsg)) {
if(cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
- memcpy(peer_fds, CMSG_DATA(cmsg), 3 * sizeof(int));
+ int passed_fd_count = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof (int);
+ if(i <= 3) {
+ memcpy(&peer_fds[i], CMSG_DATA(cmsg), passed_fd_count * sizeof(int));
+
+ } else {
+ int * reject_fds = (int *) CMSG_DATA(cmsg);
+ for(int fd = 0; fd < passed_fd_count; fd++) {
+ close(reject_fds[fd]);
+ }
+ }
+ i += passed_fd_count;
}
}
- return peer_fds;
+ if(i != 3) {
+ /* if the peer sent too many fds, we closed the excess ones
+ * in the reject_fds clause above and now we'll close the
+ * first three.
+ * if they sent too few, we'll close whatever they sent
+ */
+
+ if(peer_fds[0] >=0) close(peer_fds[0]);
+ if(peer_fds[1] >=0) close(peer_fds[1]);
+ if(peer_fds[2] >=0) close(peer_fds[2]);
+ return NULL;
+ } else {
+ return peer_fds;
+ }
}
int start_lua_child(lua_State *L,