1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
From f7a79879c0b2bef0dadd6caaaeeb0d26423e04e5 Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Thu, 13 Jan 2022 11:28:36 +0530
Subject: [PATCH] realpath: Set errno to ENAMETOOLONG for result larger than
PATH_MAX [BZ #28770]
realpath returns an allocated string when the result exceeds PATH_MAX,
which is unexpected when its second argument is not NULL. This results
in the second argument (resolved) being uninitialized and also results
in a memory leak since the caller expects resolved to be the same as the
returned value.
Return NULL and set errno to ENAMETOOLONG if the result exceeds
PATH_MAX. This fixes [BZ #28770], which is CVE-2021-3998.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit ee8d5e33adb284601c00c94687bc907e10aec9bb)
---
NEWS | 6 +++++
stdlib/Makefile | 1 +
stdlib/canonicalize.c | 12 +++++++++--
stdlib/tst-realpath-toolong.c | 49 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 65 insertions(+), 2 deletions(-)
create mode 100644 stdlib/tst-realpath-toolong.c
diff --git a/NEWS b/NEWS
index 711420cb..db50b2af 100644
--- a/NEWS
+++ b/NEWS
@@ -17,8 +17,14 @@ Security related changes:
CVE-2022-23218: Passing an overlong file name to the svcunix_create
legacy function could result in a stack-based buffer overflow.
+ CVE-2021-3998: Passing a path longer than PATH_MAX to the realpath
+ function could result in a memory leak and potential access of
+ uninitialized memory. Reported by Qualys.
+
The following bugs are resolved with this release:
+ [12889] nptl: Fix race between pthread_kill and thread exit
+ [19193] nptl: pthread_kill, pthread_cancel should not fail after exit
[22542] CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix"
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 9bb5c221..a4ac30d1 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -109,6 +109,7 @@ tests := \
tst-random \
tst-random2 \
tst-realpath \
+ tst-realpath-toolong \
tst-secure-getenv \
tst-setcontext \
tst-setcontext2 \
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index 698f9ede..7a23a51b 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -400,8 +400,16 @@ realpath_stk (const char *name, char *resolved,
error:
*dest++ = '\0';
- if (resolved != NULL && dest - rname <= get_path_max ())
- rname = strcpy (resolved, rname);
+ if (resolved != NULL)
+ {
+ if (dest - rname <= get_path_max ())
+ rname = strcpy (resolved, rname);
+ else
+ {
+ failed = true;
+ __set_errno (ENAMETOOLONG);
+ }
+ }
error_nomem:
scratch_buffer_free (&extra_buffer);
diff --git a/stdlib/tst-realpath-toolong.c b/stdlib/tst-realpath-toolong.c
new file mode 100644
index 00000000..8bed7724
--- /dev/null
+++ b/stdlib/tst-realpath-toolong.c
@@ -0,0 +1,49 @@
+/* Verify that realpath returns NULL with ENAMETOOLONG if the result exceeds
+ NAME_MAX.
+ Copyright The GNU Toolchain Authors.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <support/check.h>
+#include <support/temp_file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define BASENAME "tst-realpath-toolong."
+
+int
+do_test (void)
+{
+ char *base = support_create_and_chdir_toolong_temp_directory (BASENAME);
+
+ char buf[PATH_MAX + 1];
+ const char *res = realpath (".", buf);
+
+ /* canonicalize.c states that if the real path is >= PATH_MAX, then
+ realpath returns NULL and sets ENAMETOOLONG. */
+ TEST_VERIFY (res == NULL);
+ TEST_VERIFY (errno == ENAMETOOLONG);
+
+ free (base);
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.27.0
|