67 lines
2.5 KiB
Diff
67 lines
2.5 KiB
Diff
From 7f486ea6eebf0afce74f2e59763b9b82b78629dc Mon Sep 17 00:00:00 2001
|
|
From: Yossi Gottlieb <yossigo@gmail.com>
|
|
Date: Wed, 11 Oct 2023 22:45:34 +0300
|
|
Subject: [PATCH] Fix issue of listen before chmod on Unix sockets
|
|
(CVE-2023-45145)
|
|
|
|
Before this commit, Unix socket setup performed chmod(2) on the socket
|
|
file after calling listen(2). Depending on what umask is used, this
|
|
could leave the file with the wrong permissions for a short period of
|
|
time. As a result, another process could exploit this race condition and
|
|
establish a connection that would otherwise not be possible.
|
|
|
|
We now make sure the socket permissions are set up prior to calling
|
|
listen(2).
|
|
|
|
(cherry picked from commit a11b3bc34a054818f2ac70e50adfc542ca1cba42)
|
|
---
|
|
src/anet.c | 11 ++++++-----
|
|
1 file changed, 6 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/src/anet.c b/src/anet.c
|
|
index dc88eb7..d0db80f 100644
|
|
--- a/src/anet.c
|
|
+++ b/src/anet.c
|
|
@@ -437,13 +437,16 @@ int anetWrite(int fd, char *buf, int count)
|
|
return totlen;
|
|
}
|
|
|
|
-static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog) {
|
|
+static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog, mode_t perm) {
|
|
if (bind(s,sa,len) == -1) {
|
|
anetSetError(err, "bind: %s", strerror(errno));
|
|
close(s);
|
|
return ANET_ERR;
|
|
}
|
|
|
|
+ if (sa->sa_family == AF_LOCAL && perm)
|
|
+ chmod(((struct sockaddr_un *) sa)->sun_path, perm);
|
|
+
|
|
if (listen(s, backlog) == -1) {
|
|
anetSetError(err, "listen: %s", strerror(errno));
|
|
close(s);
|
|
@@ -484,7 +487,7 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl
|
|
|
|
if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error;
|
|
if (anetSetReuseAddr(err,s) == ANET_ERR) goto error;
|
|
- if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog) == ANET_ERR) s = ANET_ERR;
|
|
+ if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog,0) == ANET_ERR) s = ANET_ERR;
|
|
goto end;
|
|
}
|
|
if (p == NULL) {
|
|
@@ -521,10 +524,8 @@ int anetUnixServer(char *err, char *path, mode_t perm, int backlog)
|
|
memset(&sa,0,sizeof(sa));
|
|
sa.sun_family = AF_LOCAL;
|
|
strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
|
|
- if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog) == ANET_ERR)
|
|
+ if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog,perm) == ANET_ERR)
|
|
return ANET_ERR;
|
|
- if (perm)
|
|
- chmod(sa.sun_path, perm);
|
|
return s;
|
|
}
|
|
|
|
--
|
|
2.33.0
|
|
|