/[packages]/updates/5/glibc/current/SOURCES/132-glob-Simplify-the-interface-for-the-GLOB_ALTDIRFUNC-.patch
ViewVC logotype

Contents of /updates/5/glibc/current/SOURCES/132-glob-Simplify-the-interface-for-the-GLOB_ALTDIRFUNC-.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1017669 - (show annotations) (download)
Sun May 22 17:36:08 2016 UTC (7 years, 11 months ago) by tmb
File size: 8703 byte(s)
- glob: Simplify the interface for the GLOB_ALTDIRFUNC callback gl_readdir
- CVE-2016-1234: glob: Do not copy d_name field of struct dirent [BZ #19779]
- CVE-2016-3075: Stack overflow in _nss_dns_getnetbyname_r [BZ #19879]
- CVE-2016-3706: getaddrinfo: stack overflow in hostent conversion [BZ #20010]


1 From 5ae82aa4bf45cdaafeb1c25e09897eabff210de9 Mon Sep 17 00:00:00 2001
2 From: Florian Weimer <fweimer@redhat.com>
3 Date: Fri, 29 Apr 2016 09:33:07 +0200
4 Subject: [PATCH] glob: Simplify the interface for the GLOB_ALTDIRFUNC callback gl_readdir
5
6 Previously, application code had to set up the d_namlen member if
7 the target supported it, involving conditional compilation. After
8 this change, glob will use the length of the string in d_name instead
9 of d_namlen to determine the file name length. All glibc targets
10 provide the d_type and d_ino members, and setting them as needed for
11 gl_readdir is straightforward.
12
13 Changing the behavior with regards to d_ino is left to a future
14 cleanup.
15
16 (cherry picked from commit 137fe72eca6923a00381a3ca9f0e7672c1f85e3f)
17 ---
18 ChangeLog | 15 +++++++++++++++
19 manual/examples/mkdirent.c | 42 ++++++++++++++++++++++++++++++++++++++++++
20 manual/pattern.texi | 39 ++++++++++++++++++++++++++++++++++++++-
21 posix/bug-glob2.c | 2 +-
22 posix/glob.c | 24 +++---------------------
23 posix/tst-gnuglob.c | 2 +-
24 6 files changed, 100 insertions(+), 24 deletions(-)
25 create mode 100644 manual/examples/mkdirent.c
26
27 #diff --git a/ChangeLog b/ChangeLog
28 #index ac7f870..cb3db03 100644
29 #--- a/ChangeLog
30 #+++ b/ChangeLog
31 #@@ -1,3 +1,18 @@
32 #+2016-04-29 Florian Weimer <fweimer@redhat.com>
33 #+
34 #+ glob: Simplify and document the interface for the GLOB_ALTDIRFUNC
35 #+ callback function gl_readdir.
36 #+ * posix/glob.c (NAMELEN, CONVERT_D_NAMLEN): Remove.
37 #+ (CONVERT_DIRENT_DIRENT64): Use strcpy instead of memcpy.
38 #+ (glob_in_dir): Remove len. Use strdup instead of malloc and
39 #+ memcpy to copy the name.
40 #+ * manual/pattern.texi (Calling Glob): Document requirements for
41 #+ implementations of the gl_readdir callback function.
42 #+ * manual/examples/mkdirent.c: New example.
43 #+ * posix/bug-glob2.c (my_readdir): Set d_ino to 1 unconditionally,
44 #+ per the manual guidance.
45 #+ * posix/tst-gnuglob.c (my_readdir): Likewise.
46 #+
47 # 2016-04-28 Stefan Liebler <stli@linux.vnet.ibm.com>
48 #
49 # [BZ #18508]
50 diff --git a/manual/examples/mkdirent.c b/manual/examples/mkdirent.c
51 new file mode 100644
52 index 0000000..f8400f4
53 --- /dev/null
54 +++ b/manual/examples/mkdirent.c
55 @@ -0,0 +1,42 @@
56 +/* Example for creating a struct dirent object for use with glob.
57 + Copyright (C) 2016 Free Software Foundation, Inc.
58 +
59 + This program is free software; you can redistribute it and/or
60 + modify it under the terms of the GNU General Public License
61 + as published by the Free Software Foundation; either version 2
62 + of the License, or (at your option) any later version.
63 +
64 + This program is distributed in the hope that it will be useful,
65 + but WITHOUT ANY WARRANTY; without even the implied warranty of
66 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
67 + GNU General Public License for more details.
68 +
69 + You should have received a copy of the GNU General Public License
70 + along with this program; if not, if not, see <http://www.gnu.org/licenses/>.
71 +*/
72 +
73 +#include <dirent.h>
74 +#include <errno.h>
75 +#include <stddef.h>
76 +#include <stdlib.h>
77 +#include <string.h>
78 +
79 +struct dirent *
80 +mkdirent (const char *name)
81 +{
82 + size_t dirent_size = offsetof (struct dirent, d_name) + 1;
83 + size_t name_length = strlen (name);
84 + size_t total_size = dirent_size + name_length;
85 + if (total_size < dirent_size)
86 + {
87 + errno = ENOMEM;
88 + return NULL;
89 + }
90 + struct dirent *result = malloc (total_size);
91 + if (result == NULL)
92 + return NULL;
93 + result->d_type = DT_UNKNOWN;
94 + result->d_ino = 1; /* Do not skip this entry. */
95 + memcpy (result->d_name, name, name_length + 1);
96 + return result;
97 +}
98 diff --git a/manual/pattern.texi b/manual/pattern.texi
99 index da848c3..4cf26a7 100644
100 --- a/manual/pattern.texi
101 +++ b/manual/pattern.texi
102 @@ -237,7 +237,44 @@ function used to read the contents of a directory. It is used if the
103 @code{GLOB_ALTDIRFUNC} bit is set in the flag parameter. The type of
104 this field is @w{@code{struct dirent *(*) (void *)}}.
105
106 -This is a GNU extension.
107 +An implementation of @code{gl_readdir} needs to initialize the following
108 +members of the @code{struct dirent} object:
109 +
110 +@table @code
111 +@item d_type
112 +This member should be set to the file type of the entry if it is known.
113 +Otherwise, the value @code{DT_UNKNOWN} can be used. The @code{glob}
114 +function may use the specified file type to avoid callbacks in cases
115 +where the file type indicates that the data is not required.
116 +
117 +@item d_ino
118 +This member needs to be non-zero, otherwise @code{glob} may skip the
119 +current entry and call the @code{gl_readdir} callback function again to
120 +retrieve another entry.
121 +
122 +@item d_name
123 +This member must be set to the name of the entry. It must be
124 +null-terminated.
125 +@end table
126 +
127 +The example below shows how to allocate a @code{struct dirent} object
128 +containing a given name.
129 +
130 +@smallexample
131 +@include mkdirent.c.texi
132 +@end smallexample
133 +
134 +The @code{glob} function reads the @code{struct dirent} members listed
135 +above and makes a copy of the file name in the @code{d_name} member
136 +immediately after the @code{gl_readdir} callback function returns.
137 +Future invocations of any of the callback functions may dealloacte or
138 +reuse the buffer. It is the responsibility of the caller of the
139 +@code{glob} function to allocate and deallocate the buffer, around the
140 +call to @code{glob} or using the callback functions. For example, an
141 +application could allocate the buffer in the @code{gl_readdir} callback
142 +function, and deallocate it in the @code{gl_closedir} callback function.
143 +
144 +The @code{gl_readdir} member is a GNU extension.
145
146 @item gl_opendir
147 The address of an alternative implementation of the @code{opendir}
148 diff --git a/posix/bug-glob2.c b/posix/bug-glob2.c
149 index 8e21deb..1b1ca5a 100644
150 --- a/posix/bug-glob2.c
151 +++ b/posix/bug-glob2.c
152 @@ -193,7 +193,7 @@ my_readdir (void *gdir)
153 return NULL;
154 }
155
156 - dir->d.d_ino = dir->idx;
157 + dir->d.d_ino = 1; /* glob should not skip this entry. */
158
159 #ifdef _DIRENT_HAVE_D_TYPE
160 dir->d.d_type = filesystem[dir->idx].type;
161 diff --git a/posix/glob.c b/posix/glob.c
162 index f143108..0574913 100644
163 --- a/posix/glob.c
164 +++ b/posix/glob.c
165 @@ -57,10 +57,8 @@
166
167 #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
168 # include <dirent.h>
169 -# define NAMLEN(dirent) strlen((dirent)->d_name)
170 #else
171 # define dirent direct
172 -# define NAMLEN(dirent) (dirent)->d_namlen
173 # ifdef HAVE_SYS_NDIR_H
174 # include <sys/ndir.h>
175 # endif
176 @@ -76,12 +74,6 @@
177 #endif
178
179
180 -/* In GNU systems, <dirent.h> defines this macro for us. */
181 -#ifdef _D_NAMLEN
182 -# undef NAMLEN
183 -# define NAMLEN(d) _D_NAMLEN(d)
184 -#endif
185 -
186 /* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
187 if the `d_type' member for `struct dirent' is available.
188 HAVE_STRUCT_DIRENT_D_TYPE plays the same role in GNULIB. */
189 @@ -105,12 +97,6 @@
190
191 /* If the system has the `struct dirent64' type we use it internally. */
192 #if defined _LIBC && !defined COMPILE_GLOB64
193 -# if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
194 -# define CONVERT_D_NAMLEN(d64, d32)
195 -# else
196 -# define CONVERT_D_NAMLEN(d64, d32) \
197 - (d64)->d_namlen = (d32)->d_namlen;
198 -# endif
199
200 # if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
201 # define CONVERT_D_INO(d64, d32)
202 @@ -127,8 +113,7 @@
203 # endif
204
205 # define CONVERT_DIRENT_DIRENT64(d64, d32) \
206 - memcpy ((d64)->d_name, (d32)->d_name, NAMLEN (d32) + 1); \
207 - CONVERT_D_NAMLEN (d64, d32) \
208 + strcpy ((d64)->d_name, (d32)->d_name); \
209 CONVERT_D_INO (d64, d32) \
210 CONVERT_D_TYPE (d64, d32)
211 #endif
212 @@ -1562,7 +1547,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
213 while (1)
214 {
215 const char *name;
216 - size_t len;
217 #if defined _LIBC && !defined COMPILE_GLOB64
218 struct dirent64 *d;
219 union
220 @@ -1630,12 +1614,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
221 names = newnames;
222 cur = 0;
223 }
224 - len = NAMLEN (d);
225 - names->name[cur] = (char *) malloc (len + 1);
226 + names->name[cur] = strdup (d->d_name);
227 if (names->name[cur] == NULL)
228 goto memory_error;
229 - *((char *) mempcpy (names->name[cur++], name, len))
230 - = '\0';
231 + ++cur;
232 ++nfound;
233 }
234 }
235 diff --git a/posix/tst-gnuglob.c b/posix/tst-gnuglob.c
236 index 1c72357..48c7527 100644
237 --- a/posix/tst-gnuglob.c
238 +++ b/posix/tst-gnuglob.c
239 @@ -211,7 +211,7 @@ my_readdir (void *gdir)
240 return NULL;
241 }
242
243 - dir->d.d_ino = dir->idx;
244 + dir->d.d_ino = 1; /* glob should not skip this entry. */
245
246 #ifdef _DIRENT_HAVE_D_TYPE
247 dir->d.d_type = filesystem[dir->idx].type;
248 --
249 1.7.1
250

  ViewVC Help
Powered by ViewVC 1.1.30