126 lines
3.8 KiB
Diff
126 lines
3.8 KiB
Diff
From e0eef5aac453fa98a2664416a56c50ad1d00cb30 Mon Sep 17 00:00:00 2001
|
|
From: Matthias Gerstner <matthias.gerstner@suse.de>
|
|
Date: Mon, 12 May 2025 15:26:11 +0200
|
|
Subject: [PATCH 2/3] fix CVE-2025-46804: avoid file existence test information
|
|
leaks
|
|
|
|
In setuid-root context the current error messages give away whether
|
|
certain paths not accessible by the real user exist and what type they
|
|
have. To prevent this only output generic error messages in setuid-root
|
|
context.
|
|
|
|
In some situations, when an error is pertaining a directory and the
|
|
directory is owner by the real user then we can still output more
|
|
detailed diagnostics.
|
|
|
|
This change can lead to less helpful error messages when Screen is
|
|
install setuid-root. More complex changes would be needed to avoid this
|
|
(e.g. only open the `SocketPath` with raised privileges when
|
|
multi-attach is requested).
|
|
|
|
There might still be lingering some code paths that allow such
|
|
information leaks, since `SocketPath` is a global variable that is used
|
|
across the code base. The majority of issues should be caught with this
|
|
fix, however.
|
|
---
|
|
screen.c | 45 ++++++++++++++++++++++++++++++++++-----------
|
|
socket.c | 9 +++++++--
|
|
2 files changed, 41 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/screen.c b/screen.c
|
|
index 1a23e1a..6eec151 100644
|
|
--- a/screen.c
|
|
+++ b/screen.c
|
|
@@ -1122,15 +1122,28 @@ int main(int ac, char** av)
|
|
#endif
|
|
}
|
|
|
|
- if (stat(SockPath, &st) == -1)
|
|
- Panic(errno, "Cannot access %s", SockPath);
|
|
- else
|
|
- if (!S_ISDIR(st.st_mode))
|
|
+ if (stat(SockPath, &st) == -1) {
|
|
+ if (eff_uid == real_uid) {
|
|
+ Panic(errno, "Cannot access %s", SockPath);
|
|
+ } else {
|
|
+ Panic(0, "Error accessing %s", SockPath);
|
|
+ }
|
|
+ } else if (!S_ISDIR(st.st_mode)) {
|
|
+ if (eff_uid == real_uid || st.st_uid == real_uid) {
|
|
Panic(0, "%s is not a directory.", SockPath);
|
|
+ } else {
|
|
+ Panic(0, "Error accessing %s", SockPath);
|
|
+ }
|
|
+ }
|
|
#ifdef MULTIUSER
|
|
if (multi) {
|
|
- if ((int)st.st_uid != multi_uid)
|
|
- Panic(0, "%s is not the owner of %s.", multi, SockPath);
|
|
+ if ((int)st.st_uid != multi_uid) {
|
|
+ if (eff_uid == real_uid || st.st_uid == real_uid) {
|
|
+ Panic(0, "%s is not the owner of %s.", multi, SockPath);
|
|
+ } else {
|
|
+ Panic(0, "Error accessing %s", SockPath);
|
|
+ }
|
|
+ }
|
|
}
|
|
else
|
|
#endif
|
|
@@ -1144,9 +1157,13 @@ int main(int ac, char** av)
|
|
Panic(0, "You are not the owner of %s.", SockPath);
|
|
#endif
|
|
}
|
|
-
|
|
- if ((st.st_mode & 0777) != 0700)
|
|
- Panic(0, "Directory %s must have mode 700.", SockPath);
|
|
+ if ((st.st_mode & 0777) != 0700) {
|
|
+ if (eff_uid == real_uid || st.st_uid == real_uid) {
|
|
+ Panic(0, "Directory %s must have mode 700.", SockPath);
|
|
+ } else {
|
|
+ Panic(0, "Error accessing %s", SockPath);
|
|
+ }
|
|
+ }
|
|
if (SockMatch && index(SockMatch, '/'))
|
|
Panic(0, "Bad session name '%s'", SockMatch);
|
|
SockName = SockPath + strlen(SockPath) + 1;
|
|
@@ -1184,8 +1201,14 @@ int main(int ac, char** av)
|
|
else
|
|
exit(9 + (fo || oth ? 1 : 0) + fo);
|
|
}
|
|
- if (fo == 0)
|
|
- Panic(0, "No Sockets found in %s.\n", SockPath);
|
|
+ if (fo == 0) {
|
|
+ if (eff_uid == real_uid || st.st_uid == real_uid) {
|
|
+ Panic(0, "No Sockets found in %s.\n", SockPath);
|
|
+ } else {
|
|
+ Panic(0, "Error accessing %s", SockPath);
|
|
+ }
|
|
+ }
|
|
+
|
|
Msg(0, "%d Socket%s in %s.", fo, fo > 1 ? "s" : "", SockPath);
|
|
eexit(0);
|
|
}
|
|
diff --git a/socket.c b/socket.c
|
|
index 54d8cb8..6c3502f 100644
|
|
--- a/socket.c
|
|
+++ b/socket.c
|
|
@@ -169,8 +169,13 @@ bool *is_sock;
|
|
xsetegid(real_gid);
|
|
#endif
|
|
|
|
- if ((dirp = opendir(SockPath)) == 0)
|
|
- Panic(errno, "Cannot opendir %s", SockPath);
|
|
+ if ((dirp = opendir(SockPath)) == 0) {
|
|
+ if (eff_uid == real_uid) {
|
|
+ Panic(errno, "Cannot opendir %s", SockPath);
|
|
+ } else {
|
|
+ Panic(0, "Error accessing %s", SockPath);
|
|
+ }
|
|
+ }
|
|
|
|
slist = 0;
|
|
slisttail = &slist;
|
|
--
|
|
2.43.5
|
|
|