fix(ipc): reject unconnected backlog clients

This commit is contained in:
2026-08-14 22:46:29 +09:00
parent a637f457f7
commit 8df43cecd8
2 changed files with 12 additions and 7 deletions

3
ipc.c
View File

@@ -183,8 +183,7 @@ ipcconnect(void)
if(until < 0) if(until < 0)
goto Bad; goto Bad;
if(connect(fd, (struct sockaddr*)&addr, sizeof addr) < 0){ if(connect(fd, (struct sockaddr*)&addr, sizeof addr) < 0){
if(errno != EINPROGRESS && errno != EALREADY && errno != EINTR && if(errno != EINPROGRESS && errno != EALREADY && errno != EINTR)
errno != EAGAIN && errno != EWOULDBLOCK)
goto Bad; goto Bad;
if(waitfd(fd, POLLOUT, until) < 0) if(waitfd(fd, POLLOUT, until) < 0)
goto Bad; goto Bad;

View File

@@ -385,9 +385,9 @@ ipcconnectcloexec(struct ct *t)
struct sockaddr_un addr; struct sockaddr_un addr;
char root[] = "/tmp/strans-ipc.XXXXXX"; char root[] = "/tmp/strans-ipc.XXXXXX";
char *old, *saved; char *old, *saved;
int accepted, client, flags, listener; int accepted, client, flags, full, listener;
accepted = client = listener = -1; accepted = client = full = listener = -1;
old = getenv("XDG_RUNTIME_DIR"); old = getenv("XDG_RUNTIME_DIR");
saved = old == nil ? nil : strdup(old); saved = old == nil ? nil : strdup(old);
if(mkdtemp(root) == nil){ if(mkdtemp(root) == nil){
@@ -401,19 +401,25 @@ ipcconnectcloexec(struct ct *t)
if(ipcpath(addr.sun_path, sizeof addr.sun_path) < 0 || if(ipcpath(addr.sun_path, sizeof addr.sun_path) < 0 ||
(listener = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 || (listener = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 ||
bind(listener, (struct sockaddr*)&addr, sizeof addr) < 0 || bind(listener, (struct sockaddr*)&addr, sizeof addr) < 0 ||
listen(listener, 1) < 0){ listen(listener, 0) < 0){
CT_ERRORF(t, "listen failed: %s", strerror(errno)); CT_ERRORF(t, "listen failed: %s", strerror(errno));
goto Out; goto Out;
} }
client = ipcconnect(); client = ipcconnect();
if(!CT_CHECK(t, client >= 0)) if(!CT_CHECK(t, client >= 0))
goto Out; goto Out;
flags = fcntl(client, F_GETFD);
CT_CHECK(t, flags >= 0 && (flags & FD_CLOEXEC) != 0);
errno = 0;
full = ipcconnect();
CT_EQ_INT(t, -1, full);
CT_CHECK(t, errno == EAGAIN || errno == EWOULDBLOCK);
accepted = accept(listener, nil, nil); accepted = accept(listener, nil, nil);
if(!CT_CHECK(t, accepted >= 0)) if(!CT_CHECK(t, accepted >= 0))
goto Out; goto Out;
flags = fcntl(client, F_GETFD);
CT_CHECK(t, flags >= 0 && (flags & FD_CLOEXEC) != 0);
Out: Out:
if(full >= 0)
close(full);
if(accepted >= 0) if(accepted >= 0)
close(accepted); close(accepted);
if(client >= 0) if(client >= 0)