diff options
author | Xiangyu Chen <xiangyu.chen@windriver.com> | 2023-10-20 19:50:30 +0800 |
---|---|---|
committer | Steve Sakoman <steve@sakoman.com> | 2023-11-11 08:23:01 -1000 |
commit | 197d1d8cd66026b9dc5d8c53a87b9c82628bff86 (patch) | |
tree | d8aacbf04cdef6927d9894bb0105a061368c4f12 | |
parent | eefb8f69cebc052f2fe4f081ce6f74413df099f7 (diff) | |
download | poky-197d1d8cd66026b9dc5d8c53a87b9c82628bff86.tar.gz |
shadow: Fix CVE-2023-4641
shadow-utils: possible password leak during passwd(1) change
(From OE-Core rev: 3623f48ff73ad97f583172b7dbfcb56affc9353b)
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r-- | meta/recipes-extended/shadow/files/CVE-2023-4641.patch | 147 | ||||
-rw-r--r-- | meta/recipes-extended/shadow/shadow.inc | 1 |
2 files changed, 148 insertions, 0 deletions
diff --git a/meta/recipes-extended/shadow/files/CVE-2023-4641.patch b/meta/recipes-extended/shadow/files/CVE-2023-4641.patch new file mode 100644 index 0000000000..1fabfe928e --- /dev/null +++ b/meta/recipes-extended/shadow/files/CVE-2023-4641.patch | |||
@@ -0,0 +1,147 @@ | |||
1 | From 25dbe2ce166a13322b7536ff2f738786ea2e61e7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Alejandro Colomar <alx@kernel.org> | ||
3 | Date: Sat, 10 Jun 2023 16:20:05 +0200 | ||
4 | Subject: [PATCH] gpasswd(1): Fix password leak | ||
5 | |||
6 | How to trigger this password leak? | ||
7 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
8 | |||
9 | When gpasswd(1) asks for the new password, it asks twice (as is usual | ||
10 | for confirming the new password). Each of those 2 password prompts | ||
11 | uses agetpass() to get the password. If the second agetpass() fails, | ||
12 | the first password, which has been copied into the 'static' buffer | ||
13 | 'pass' via STRFCPY(), wasn't being zeroed. | ||
14 | |||
15 | agetpass() is defined in <./libmisc/agetpass.c> (around line 91), and | ||
16 | can fail for any of the following reasons: | ||
17 | |||
18 | - malloc(3) or readpassphrase(3) failure. | ||
19 | |||
20 | These are going to be difficult to trigger. Maybe getting the system | ||
21 | to the limits of memory utilization at that exact point, so that the | ||
22 | next malloc(3) gets ENOMEM, and possibly even the OOM is triggered. | ||
23 | About readpassphrase(3), ENFILE and EINTR seem the only plausible | ||
24 | ones, and EINTR probably requires privilege or being the same user; | ||
25 | but I wouldn't discard ENFILE so easily, if a process starts opening | ||
26 | files. | ||
27 | |||
28 | - The password is longer than PASS_MAX. | ||
29 | |||
30 | The is plausible with physical access. However, at that point, a | ||
31 | keylogger will be a much simpler attack. | ||
32 | |||
33 | And, the attacker must be able to know when the second password is being | ||
34 | introduced, which is not going to be easy. | ||
35 | |||
36 | How to read the password after the leak? | ||
37 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
38 | |||
39 | Provoking the leak yourself at the right point by entering a very long | ||
40 | password is easy, and inspecting the process stack at that point should | ||
41 | be doable. Try to find some consistent patterns. | ||
42 | |||
43 | Then, search for those patterns in free memory, right after the victim | ||
44 | leaks their password. | ||
45 | |||
46 | Once you get the leak, a program should read all the free memory | ||
47 | searching for patterns that gpasswd(1) leaves nearby the leaked | ||
48 | password. | ||
49 | |||
50 | On 6/10/23 03:14, Seth Arnold wrote: | ||
51 | > An attacker process wouldn't be able to use malloc(3) for this task. | ||
52 | > There's a handful of tools available for userspace to allocate memory: | ||
53 | > | ||
54 | > - brk / sbrk | ||
55 | > - mmap MAP_ANONYMOUS | ||
56 | > - mmap /dev/zero | ||
57 | > - mmap some other file | ||
58 | > - shm_open | ||
59 | > - shmget | ||
60 | > | ||
61 | > Most of these return only pages of zeros to a process. Using mmap of an | ||
62 | > existing file, you can get some of the contents of the file demand-loaded | ||
63 | > into the memory space on the first use. | ||
64 | > | ||
65 | > The MAP_UNINITIALIZED flag only works if the kernel was compiled with | ||
66 | > CONFIG_MMAP_ALLOW_UNINITIALIZED. This is rare. | ||
67 | > | ||
68 | > malloc(3) doesn't zero memory, to our collective frustration, but all the | ||
69 | > garbage in the allocations is from previous allocations in the current | ||
70 | > process. It isn't leftover from other processes. | ||
71 | > | ||
72 | > The avenues available for reading the memory: | ||
73 | > - /dev/mem and /dev/kmem (requires root, not available with Secure Boot) | ||
74 | > - /proc/pid/mem (requires ptrace privileges, mediated by YAMA) | ||
75 | > - ptrace (requires ptrace privileges, mediated by YAMA) | ||
76 | > - causing memory to be swapped to disk, and then inspecting the swap | ||
77 | > | ||
78 | > These all require a certain amount of privileges. | ||
79 | |||
80 | How to fix it? | ||
81 | ~~~~~~~~~~~~~~ | ||
82 | |||
83 | memzero(), which internally calls explicit_bzero(3), or whatever | ||
84 | alternative the system provides with a slightly different name, will | ||
85 | make sure that the buffer is zeroed in memory, and optimizations are not | ||
86 | allowed to impede this zeroing. | ||
87 | |||
88 | This is not really 100% effective, since compilers may place copies of | ||
89 | the string somewhere hidden in the stack. Those copies won't get zeroed | ||
90 | by explicit_bzero(3). However, that's arguably a compiler bug, since | ||
91 | compilers should make everything possible to avoid optimizing strings | ||
92 | that are later passed to explicit_bzero(3). But we all know that | ||
93 | sometimes it's impossible to have perfect knowledge in the compiler, so | ||
94 | this is plausible. Nevertheless, there's nothing we can do against such | ||
95 | issues, except minimizing the time such passwords are stored in plain | ||
96 | text. | ||
97 | |||
98 | Security concerns | ||
99 | ~~~~~~~~~~~~~~~~~ | ||
100 | |||
101 | We believe this isn't easy to exploit. Nevertheless, and since the fix | ||
102 | is trivial, this fix should probably be applied soon, and backported to | ||
103 | all supported distributions, to prevent someone else having more | ||
104 | imagination than us to find a way. | ||
105 | |||
106 | Affected versions | ||
107 | ~~~~~~~~~~~~~~~~~ | ||
108 | |||
109 | All. Bug introduced in shadow 19990709. That's the second commit in | ||
110 | the git history. | ||
111 | |||
112 | Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)") | ||
113 | |||
114 | CVE: CVE-2023-4641 | ||
115 | Upstream-Status: Backport [https://github.com/shadow-maint/shadow/commit/65c88a43a23c2391dcc90c0abda3e839e9c57904] | ||
116 | |||
117 | Reported-by: Alejandro Colomar <alx@kernel.org> | ||
118 | Cc: Serge Hallyn <serge@hallyn.com> | ||
119 | Cc: Iker Pedrosa <ipedrosa@redhat.com> | ||
120 | Cc: Seth Arnold <seth.arnold@canonical.com> | ||
121 | Cc: Christian Brauner <christian@brauner.io> | ||
122 | Cc: Balint Reczey <rbalint@debian.org> | ||
123 | Cc: Sam James <sam@gentoo.org> | ||
124 | Cc: David Runge <dvzrv@archlinux.org> | ||
125 | Cc: Andreas Jaeger <aj@suse.de> | ||
126 | Cc: <~hallyn/shadow@lists.sr.ht> | ||
127 | Signed-off-by: Alejandro Colomar <alx@kernel.org> | ||
128 | Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com> | ||
129 | --- | ||
130 | src/gpasswd.c | 1 + | ||
131 | 1 file changed, 1 insertion(+) | ||
132 | |||
133 | diff --git a/src/gpasswd.c b/src/gpasswd.c | ||
134 | index 5983f787..2d8869ef 100644 | ||
135 | --- a/src/gpasswd.c | ||
136 | +++ b/src/gpasswd.c | ||
137 | @@ -896,6 +896,7 @@ static void change_passwd (struct group *gr) | ||
138 | strzero (cp); | ||
139 | cp = getpass (_("Re-enter new password: ")); | ||
140 | if (NULL == cp) { | ||
141 | + memzero (pass, sizeof pass); | ||
142 | exit (1); | ||
143 | } | ||
144 | |||
145 | -- | ||
146 | 2.34.1 | ||
147 | |||
diff --git a/meta/recipes-extended/shadow/shadow.inc b/meta/recipes-extended/shadow/shadow.inc index cf05a3af93..4014baddc1 100644 --- a/meta/recipes-extended/shadow/shadow.inc +++ b/meta/recipes-extended/shadow/shadow.inc | |||
@@ -17,6 +17,7 @@ SRC_URI = "${GITHUB_BASE_URI}/download/${PV}/${BP}.tar.gz \ | |||
17 | file://0001-Fix-can-not-print-full-login.patch \ | 17 | file://0001-Fix-can-not-print-full-login.patch \ |
18 | file://CVE-2023-29383.patch \ | 18 | file://CVE-2023-29383.patch \ |
19 | file://0001-Overhaul-valid_field.patch \ | 19 | file://0001-Overhaul-valid_field.patch \ |
20 | file://CVE-2023-4641.patch \ | ||
20 | " | 21 | " |
21 | 22 | ||
22 | SRC_URI:append:class-target = " \ | 23 | SRC_URI:append:class-target = " \ |