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