Commit | Line | Data |
---|---|---|
e13b5474 MB |
1 | This file contains fixes from the "release/2.28/master" branch: |
2 | https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/release/2.28/master | |
3 | ||
4 | Currently we have these commits (sans tests and ChangeLog updates): | |
5 | 7f11842e7483da7aa9fa3031be122021978ef600 | |
6 | 726e1554ce4db5e35af41cb0110c54c5e1232054 | |
7 | 4b25485f03158959cff45379eecc1d73c7dcdd11 | |
8 | d05b05d1570ba3ae354a2f5a3cfeefb373b09979 | |
9 | bfcfa22589f2b4277a65e60c6b736b6bbfbd87d0 | |
10 | 2f498f3d140ab5152bd784df2be7af7d9c5e63ed | |
11 | ||
12 | diff --git a/htl/Versions b/htl/Versions | |
13 | index 6a63a1b8a1..c5a616da10 100644 | |
14 | --- a/htl/Versions | |
15 | +++ b/htl/Versions | |
16 | @@ -150,6 +150,8 @@ libpthread { | |
17 | __cthread_keycreate; | |
18 | __cthread_getspecific; | |
19 | __cthread_setspecific; | |
20 | + __pthread_getspecific; | |
21 | + __pthread_setspecific; | |
22 | __pthread_getattr_np; | |
23 | __pthread_attr_getstack; | |
24 | } | |
25 | ||
26 | diff --git a/sysdeps/htl/pt-getspecific.c b/sysdeps/htl/pt-getspecific.c | |
27 | index a0227a67f6..64ddf9551a 100644 | |
28 | --- a/sysdeps/htl/pt-getspecific.c | |
29 | +++ b/sysdeps/htl/pt-getspecific.c | |
30 | @@ -36,3 +36,4 @@ __pthread_getspecific (pthread_key_t key) | |
31 | return self->thread_specifics[key]; | |
32 | } | |
33 | strong_alias (__pthread_getspecific, pthread_getspecific); | |
34 | +hidden_def (__pthread_getspecific) | |
35 | diff --git a/sysdeps/htl/pt-setspecific.c b/sysdeps/htl/pt-setspecific.c | |
36 | index a46a12f157..02aff417ef 100644 | |
37 | --- a/sysdeps/htl/pt-setspecific.c | |
38 | +++ b/sysdeps/htl/pt-setspecific.c | |
39 | @@ -48,3 +48,4 @@ __pthread_setspecific (pthread_key_t key, const void *value) | |
40 | return 0; | |
41 | } | |
42 | strong_alias (__pthread_setspecific, pthread_setspecific); | |
43 | +hidden_def (__pthread_setspecific) | |
44 | diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h | |
45 | index 132ac1718e..71c2fcd9c6 100644 | |
46 | --- a/sysdeps/htl/pthreadP.h | |
47 | +++ b/sysdeps/htl/pthreadP.h | |
48 | @@ -68,6 +68,8 @@ struct __pthread_cancelation_handler **___pthread_get_cleanup_stack (void) attri | |
49 | ||
50 | #if IS_IN (libpthread) | |
51 | hidden_proto (__pthread_key_create) | |
52 | +hidden_proto (__pthread_getspecific) | |
53 | +hidden_proto (__pthread_setspecific) | |
54 | hidden_proto (_pthread_mutex_init) | |
55 | #endif | |
56 | ||
57 | diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c | |
58 | index 3bde0cf4f0..bc140b5a7f 100644 | |
59 | --- a/sysdeps/unix/sysv/linux/getdents64.c | |
60 | +++ b/sysdeps/unix/sysv/linux/getdents64.c | |
61 | @@ -33,41 +33,80 @@ strong_alias (__getdents64, __getdents) | |
62 | # include <shlib-compat.h> | |
63 | ||
64 | # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) | |
65 | -# include <olddirent.h> | |
66 | +# include <olddirent.h> | |
67 | +# include <unistd.h> | |
68 | ||
69 | -/* kernel definition of as of 3.2. */ | |
70 | -struct compat_linux_dirent | |
71 | +static ssize_t | |
72 | +handle_overflow (int fd, __off64_t offset, ssize_t count) | |
73 | { | |
74 | - /* Both d_ino and d_off are compat_ulong_t which are defined in all | |
75 | - architectures as 'u32'. */ | |
76 | - uint32_t d_ino; | |
77 | - uint32_t d_off; | |
78 | - unsigned short d_reclen; | |
79 | - char d_name[1]; | |
80 | -}; | |
81 | + /* If this is the first entry in the buffer, we can report the | |
82 | + error. */ | |
83 | + if (count == 0) | |
84 | + { | |
85 | + __set_errno (EOVERFLOW); | |
86 | + return -1; | |
87 | + } | |
88 | + | |
89 | + /* Otherwise, seek to the overflowing entry, so that the next call | |
90 | + will report the error, and return the data read so far.. */ | |
91 | + if (__lseek64 (fd, offset, SEEK_SET) != 0) | |
92 | + return -1; | |
93 | + return count; | |
94 | +} | |
95 | ||
96 | ssize_t | |
97 | __old_getdents64 (int fd, char *buf, size_t nbytes) | |
98 | { | |
99 | - ssize_t retval = INLINE_SYSCALL_CALL (getdents, fd, buf, nbytes); | |
100 | + /* We do not move the individual directory entries. This is only | |
101 | + possible if the target type (struct __old_dirent64) is smaller | |
102 | + than the source type. */ | |
103 | + _Static_assert (offsetof (struct __old_dirent64, d_name) | |
104 | + <= offsetof (struct dirent64, d_name), | |
105 | + "__old_dirent64 is larger than dirent64"); | |
106 | + _Static_assert (__alignof__ (struct __old_dirent64) | |
107 | + <= __alignof__ (struct dirent64), | |
108 | + "alignment of __old_dirent64 is larger than dirent64"); | |
109 | ||
110 | - /* The kernel added the d_type value after the name. Change this now. */ | |
111 | - if (retval != -1) | |
112 | + ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes); | |
113 | + if (retval > 0) | |
114 | { | |
115 | - union | |
116 | - { | |
117 | - struct compat_linux_dirent k; | |
118 | - struct dirent u; | |
119 | - } *kbuf = (void *) buf; | |
120 | - | |
121 | - while ((char *) kbuf < buf + retval) | |
122 | + char *p = buf; | |
123 | + char *end = buf + retval; | |
124 | + while (p < end) | |
125 | { | |
126 | - char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1); | |
127 | - memmove (kbuf->u.d_name, kbuf->k.d_name, | |
128 | - strlen (kbuf->k.d_name) + 1); | |
129 | - kbuf->u.d_type = d_type; | |
130 | + struct dirent64 *source = (struct dirent64 *) p; | |
131 | + | |
132 | + /* Copy out the fixed-size data. */ | |
133 | + __ino_t ino = source->d_ino; | |
134 | + __off64_t offset = source->d_off; | |
135 | + unsigned int reclen = source->d_reclen; | |
136 | + unsigned char type = source->d_type; | |
137 | + | |
138 | + /* Check for ino_t overflow. */ | |
139 | + if (__glibc_unlikely (ino != source->d_ino)) | |
140 | + return handle_overflow (fd, offset, p - buf); | |
141 | + | |
142 | + /* Convert to the target layout. Use a separate struct and | |
143 | + memcpy to side-step aliasing issues. */ | |
144 | + struct __old_dirent64 result; | |
145 | + result.d_ino = ino; | |
146 | + result.d_off = offset; | |
147 | + result.d_reclen = reclen; | |
148 | + result.d_type = type; | |
149 | + | |
150 | + /* Write the fixed-sized part of the result to the | |
151 | + buffer. */ | |
152 | + size_t result_name_offset = offsetof (struct __old_dirent64, d_name); | |
153 | + memcpy (p, &result, result_name_offset); | |
154 | + | |
155 | + /* Adjust the position of the name if necessary. Copy | |
156 | + everything until the end of the record, including the | |
157 | + terminating NUL byte. */ | |
158 | + if (result_name_offset != offsetof (struct dirent64, d_name)) | |
159 | + memmove (p + result_name_offset, source->d_name, | |
160 | + reclen - offsetof (struct dirent64, d_name)); | |
161 | ||
162 | - kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen); | |
163 | + p += reclen; | |
164 | } | |
165 | } | |
166 | return retval; | |
167 | ||
168 | diff --git a/misc/error.c b/misc/error.c | |
169 | index b4e8b6c938..03378e2f2a 100644 | |
170 | --- a/misc/error.c | |
171 | +++ b/misc/error.c | |
172 | @@ -319,6 +319,7 @@ error (int status, int errnum, const char *message, ...) | |
173 | ||
174 | va_start (args, message); | |
175 | error_tail (status, errnum, message, args); | |
176 | + va_end (args); | |
177 | ||
178 | #ifdef _LIBC | |
179 | _IO_funlockfile (stderr); | |
180 | @@ -390,6 +391,7 @@ error_at_line (int status, int errnum, const char *file_name, | |
181 | ||
182 | va_start (args, message); | |
183 | error_tail (status, errnum, message, args); | |
184 | + va_end (args); | |
185 | ||
186 | #ifdef _LIBC | |
187 | _IO_funlockfile (stderr); | |
188 | ||
189 | diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c | |
190 | index 265a02434d..7293b795b6 100644 | |
191 | --- a/nscd/nscd_conf.c | |
192 | +++ b/nscd/nscd_conf.c | |
193 | @@ -190,7 +190,10 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) | |
194 | if (!arg1) | |
195 | error (0, 0, _("Must specify user name for server-user option")); | |
196 | else | |
197 | - server_user = xstrdup (arg1); | |
198 | + { | |
199 | + free ((char *) server_user); | |
200 | + server_user = xstrdup (arg1); | |
201 | + } | |
202 | } | |
203 | else if (strcmp (entry, "stat-user") == 0) | |
204 | { | |
205 | @@ -198,6 +201,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) | |
206 | error (0, 0, _("Must specify user name for stat-user option")); | |
207 | else | |
208 | { | |
209 | + free ((char *) stat_user); | |
210 | stat_user = xstrdup (arg1); | |
211 | ||
212 | struct passwd *pw = getpwnam (stat_user); | |
213 | ||
214 | diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c | |
215 | index cfd34b66b9..35b0bfc5d2 100644 | |
216 | --- a/nss/nss_files/files-alias.c | |
217 | +++ b/nss/nss_files/files-alias.c | |
218 | @@ -221,6 +221,13 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result, | |
219 | { | |
220 | while (! feof_unlocked (listfile)) | |
221 | { | |
222 | + if (room_left < 2) | |
223 | + { | |
224 | + free (old_line); | |
225 | + fclose (listfile); | |
226 | + goto no_more_room; | |
227 | + } | |
228 | + | |
229 | first_unused[room_left - 1] = '\xff'; | |
230 | line = fgets_unlocked (first_unused, room_left, | |
231 | listfile); | |
232 | @@ -229,6 +236,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result, | |
233 | if (first_unused[room_left - 1] != '\xff') | |
234 | { | |
235 | free (old_line); | |
236 | + fclose (listfile); | |
237 | goto no_more_room; | |
238 | } | |
239 | ||
240 | @@ -256,6 +264,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result, | |
241 | + __alignof__ (char *))) | |
242 | { | |
243 | free (old_line); | |
244 | + fclose (listfile); | |
245 | goto no_more_room; | |
246 | } | |
247 | room_left -= ((first_unused - cp) | |
248 |