| rev |
line source |
|
shann@25774
|
1 From 161f85b98b7e1d5e4893aeed20f4cdb5e3dfaaa4 Mon Sep 17 00:00:00 2001
|
|
shann@25774
|
2 From: Matthias Gerstner <matthias.gerstner@suse.de>
|
|
shann@25774
|
3 Date: Mon, 12 May 2025 15:38:19 +0200
|
|
shann@25774
|
4 Subject: fix CVE-2025-46805: socket.c - don't send signals with root
|
|
shann@25774
|
5 privileges
|
|
shann@25774
|
6
|
|
shann@25774
|
7 The CheckPid() function was introduced to address CVE-2023-24626, to
|
|
shann@25774
|
8 prevent sending SIGCONT and SIGHUP to arbitrary PIDs in the system. This
|
|
shann@25774
|
9 fix still suffers from a TOCTOU race condition. The client can replace
|
|
shann@25774
|
10 itself by a privileged process, or try to cycle PIDs until a privileged
|
|
shann@25774
|
11 process receives the original PID.
|
|
shann@25774
|
12
|
|
shann@25774
|
13 To prevent this, always send signals using the real privileges. Keep
|
|
shann@25774
|
14 CheckPid() for error diagnostics. If sending the actual signal fails
|
|
shann@25774
|
15 later on then there will be no more error reporting.
|
|
shann@25774
|
16
|
|
shann@25774
|
17 It seems the original bugfix already introduced a regression when
|
|
shann@25774
|
18 attaching to another's user session that is not owned by root. In this
|
|
shann@25774
|
19 case the target sessions runs with real uid X, while for sending a
|
|
shann@25774
|
20 signal to the `pid` provided by the client real uid Y (or root
|
|
shann@25774
|
21 privileges) are required.
|
|
shann@25774
|
22
|
|
shann@25774
|
23 This is hard to properly fix without this regression. On Linux pidfds
|
|
shann@25774
|
24 could be used to allow safely sending signals to other PIDs as root
|
|
shann@25774
|
25 without involving race conditions. In this case the client PID should
|
|
shann@25774
|
26 also be obtained via the UNIX domain socket's SO_PEERCRED option,
|
|
shann@25774
|
27 though.
|
|
shann@25774
|
28 ---
|
|
shann@25774
|
29 src/socket.c | 21 +++++++++++++--------
|
|
shann@25774
|
30 1 file changed, 13 insertions(+), 8 deletions(-)
|
|
shann@25774
|
31
|
|
shann@25774
|
32 diff --git a/socket.c b/socket.c
|
|
shann@25774
|
33 index 6c3502f..d6621fa 100644
|
|
shann@25774
|
34 --- a/socket.c
|
|
shann@25774
|
35 +++ b/socket.c
|
|
shann@25774
|
36 @@ -831,6 +831,11 @@ int pid;
|
|
shann@25774
|
37 return UserStatus();
|
|
shann@25774
|
38 }
|
|
shann@25774
|
39
|
|
shann@25774
|
40 +static void KillUnpriv(pid_t pid, int sig) {
|
|
shann@25774
|
41 + UserContext();
|
|
shann@25774
|
42 + UserReturn(kill(pid, sig));
|
|
shann@25774
|
43 +}
|
|
shann@25774
|
44 +
|
|
shann@25774
|
45 #ifdef hpux
|
|
shann@25774
|
46 /*
|
|
shann@25774
|
47 * From: "F. K. Bruner" <napalm@ugcs.caltech.edu>
|
|
shann@25774
|
48 @@ -916,14 +921,14 @@ struct win *wi;
|
|
shann@25774
|
49 {
|
|
shann@25774
|
50 Msg(errno, "Could not perform necessary sanity checks on pts device.");
|
|
shann@25774
|
51 close(i);
|
|
shann@25774
|
52 - Kill(pid, SIG_BYE);
|
|
shann@25774
|
53 + KillUnpriv(pid, SIG_BYE);
|
|
shann@25774
|
54 return -1;
|
|
shann@25774
|
55 }
|
|
shann@25774
|
56 if (strcmp(ttyname_in_ns, m->m_tty))
|
|
shann@25774
|
57 {
|
|
shann@25774
|
58 Msg(errno, "Attach: passed fd does not match tty: %s - %s!", ttyname_in_ns, m->m_tty[0] != '\0' ? m->m_tty : "(null)");
|
|
shann@25774
|
59 close(i);
|
|
shann@25774
|
60 - Kill(pid, SIG_BYE);
|
|
shann@25774
|
61 + KillUnpriv(pid, SIG_BYE);
|
|
shann@25774
|
62 return -1;
|
|
shann@25774
|
63 }
|
|
shann@25774
|
64 /* m->m_tty so far contains the actual name of the pts device in the
|
|
shann@25774
|
65 @@ -940,19 +945,19 @@ struct win *wi;
|
|
shann@25774
|
66 {
|
|
shann@25774
|
67 Msg(errno, "Attach: passed fd does not match tty: %s - %s!", m->m_tty, myttyname ? myttyname : "NULL");
|
|
shann@25774
|
68 close(i);
|
|
shann@25774
|
69 - Kill(pid, SIG_BYE);
|
|
shann@25774
|
70 + KillUnpriv(pid, SIG_BYE);
|
|
shann@25774
|
71 return -1;
|
|
shann@25774
|
72 }
|
|
shann@25774
|
73 }
|
|
shann@25774
|
74 else if ((i = secopen(m->m_tty, O_RDWR | O_NONBLOCK, 0)) < 0)
|
|
shann@25774
|
75 {
|
|
shann@25774
|
76 Msg(errno, "Attach: Could not open %s!", m->m_tty);
|
|
shann@25774
|
77 - Kill(pid, SIG_BYE);
|
|
shann@25774
|
78 + KillUnpriv(pid, SIG_BYE);
|
|
shann@25774
|
79 return -1;
|
|
shann@25774
|
80 }
|
|
shann@25774
|
81 #ifdef MULTIUSER
|
|
shann@25774
|
82 if (attach)
|
|
shann@25774
|
83 - Kill(pid, SIGCONT);
|
|
shann@25774
|
84 + KillUnpriv(pid, SIGCONT);
|
|
shann@25774
|
85 #endif
|
|
shann@25774
|
86
|
|
shann@25774
|
87 #if defined(ultrix) || defined(pyr) || defined(NeXT)
|
|
shann@25774
|
88 @@ -965,7 +970,7 @@ struct win *wi;
|
|
shann@25774
|
89 {
|
|
shann@25774
|
90 write(i, "Attaching from inside of screen?\n", 33);
|
|
shann@25774
|
91 close(i);
|
|
shann@25774
|
92 - Kill(pid, SIG_BYE);
|
|
shann@25774
|
93 + KillUnpriv(pid, SIG_BYE);
|
|
shann@25774
|
94 Msg(0, "Attach msg ignored: coming from inside.");
|
|
shann@25774
|
95 return -1;
|
|
shann@25774
|
96 }
|
|
shann@25774
|
97 @@ -976,7 +981,7 @@ struct win *wi;
|
|
shann@25774
|
98 {
|
|
shann@25774
|
99 write(i, "Access to session denied.\n", 26);
|
|
shann@25774
|
100 close(i);
|
|
shann@25774
|
101 - Kill(pid, SIG_BYE);
|
|
shann@25774
|
102 + KillUnpriv(pid, SIG_BYE);
|
|
shann@25774
|
103 Msg(0, "Attach: access denied for user %s.", user);
|
|
shann@25774
|
104 return -1;
|
|
shann@25774
|
105 }
|
|
shann@25774
|
106 @@ -1294,7 +1299,7 @@ ReceiveMsg()
|
|
shann@25774
|
107 Msg(0, "Query attempt with bad pid(%d)!", m.m.command.apid);
|
|
shann@25774
|
108 }
|
|
shann@25774
|
109 else {
|
|
shann@25774
|
110 - Kill(m.m.command.apid,
|
|
shann@25774
|
111 + KillUnpriv(m.m.command.apid,
|
|
shann@25774
|
112 (queryflag >= 0)
|
|
shann@25774
|
113 ? SIGCONT
|
|
shann@25774
|
114 : SIG_BYE); /* Send SIG_BYE if an error happened */
|
|
shann@25774
|
115 --
|
|
shann@25774
|
116 cgit v1.1
|
|
shann@25774
|
117
|
|
shann@25774
|
118
|