Skip to content

Commit 03345dd

Browse files
oranagrayossigo
andauthored
Fix issue of listen before chmod on Unix sockets (CVE-2023-45145) (redis#12671)
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 1119eca) Co-authored-by: Yossi Gottlieb <yossigo@gmail.com>
1 parent 3c734b8 commit 03345dd

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

src/anet.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -417,13 +417,16 @@ int anetUnixGenericConnect(char *err, const char *path, int flags)
417417
return s;
418418
}
419419

420-
static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog) {
420+
static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog, mode_t perm) {
421421
if (bind(s,sa,len) == -1) {
422422
anetSetError(err, "bind: %s", strerror(errno));
423423
close(s);
424424
return ANET_ERR;
425425
}
426426

427+
if (sa->sa_family == AF_LOCAL && perm)
428+
chmod(((struct sockaddr_un *) sa)->sun_path, perm);
429+
427430
if (listen(s, backlog) == -1) {
428431
anetSetError(err, "listen: %s", strerror(errno));
429432
close(s);
@@ -467,7 +470,7 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl
467470

468471
if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error;
469472
if (anetSetReuseAddr(err,s) == ANET_ERR) goto error;
470-
if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog) == ANET_ERR) s = ANET_ERR;
473+
if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog,0) == ANET_ERR) s = ANET_ERR;
471474
goto end;
472475
}
473476
if (p == NULL) {
@@ -508,10 +511,8 @@ int anetUnixServer(char *err, char *path, mode_t perm, int backlog)
508511
memset(&sa,0,sizeof(sa));
509512
sa.sun_family = AF_LOCAL;
510513
redis_strlcpy(sa.sun_path,path,sizeof(sa.sun_path));
511-
if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog) == ANET_ERR)
514+
if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog,perm) == ANET_ERR)
512515
return ANET_ERR;
513-
if (perm)
514-
chmod(sa.sun_path, perm);
515516
return s;
516517
}
517518

0 commit comments

Comments
 (0)