]> git.ipfire.org Git - people/jschlag/ipfire-2.x.git/blob - src/patches/glibc/glibc-rh1074353.patch
glibc: new RHEL6 patches / fix CVE-2015-7547 and more
[people/jschlag/ipfire-2.x.git] / src / patches / glibc / glibc-rh1074353.patch
1 commit bc8f194c8c29e46e8ee4034f06e46988dfff38f7
2 Author: Siddhesh Poyarekar <siddhesh@redhat.com>
3 Date: Wed Apr 30 12:00:39 2014 +0530
4
5 Initialize all of datahead structure in nscd (BZ #16791)
6
7 The datahead structure has an unused padding field that remains
8 uninitialized. Valgrind prints out a warning for it on querying a
9 netgroups entry. This is harmless, but is a potential data leak since
10 it would result in writing out an uninitialized byte to the cache
11 file. Besides, this happens only when there is a cache miss, so we're
12 not adding computation to any fast path.
13
14 commit 1cdeb2372ddecac0dfe0c132a033e9590ffa07d2
15 Author: Siddhesh Poyarekar <siddhesh@redhat.com>
16 Date: Wed Apr 30 11:57:09 2014 +0530
17
18 Consolidate code to initialize nscd dataset header
19
20 This patch consolidates the code to initialize the header of a dataset
21 into a single set of functions (one for positive and another for
22 negative datasets) primarily to reduce repetition of code. The
23 secondary reason is to simplify Patch 2/2 which fixes the problem of
24 an uninitialized byte in the header by initializing an unused field in
25 the structure and hence preventing a possible data leak into the cache
26 file.
27
28 diff --git a/nscd/aicache.c b/nscd/aicache.c
29 index 98d40a1..d7966bd 100644
30 --- a/nscd/aicache.c
31 +++ b/nscd/aicache.c
32 @@ -383,17 +383,12 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
33 cp = family;
34 }
35
36 - /* Fill in the rest of the dataset. */
37 - dataset->head.allocsize = total + req->key_len;
38 - dataset->head.recsize = total - offsetof (struct dataset, resp);
39 - dataset->head.notfound = false;
40 - dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
41 - dataset->head.usable = true;
42 -
43 - /* Compute the timeout time. */
44 - dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl;
45 - timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl;
46 + timeout = datahead_init_pos (&dataset->head, total + req->key_len,
47 + total - offsetof (struct dataset, resp),
48 + he == NULL ? 0 : dh->nreloads + 1,
49 + ttl == INT32_MAX ? db->postimeout : ttl);
50
51 + /* Fill in the rest of the dataset. */
52 dataset->resp.version = NSCD_VERSION;
53 dataset->resp.found = 1;
54 dataset->resp.naddrs = naddrs;
55 @@ -528,15 +523,9 @@ next_nip:
56 else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
57 + req->key_len), 1)) != NULL)
58 {
59 - dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
60 - dataset->head.recsize = total;
61 - dataset->head.notfound = true;
62 - dataset->head.nreloads = 0;
63 - dataset->head.usable = true;
64 -
65 - /* Compute the timeout time. */
66 - timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
67 - dataset->head.ttl = db->negtimeout;
68 + timeout = datahead_init_neg (&dataset->head,
69 + sizeof (struct dataset) + req->key_len,
70 + total, db->negtimeout);
71
72 /* This is the reply. */
73 memcpy (&dataset->resp, &notfound, total);
74 diff --git a/nscd/grpcache.c b/nscd/grpcache.c
75 index b5a33eb..df59fa7 100644
76 --- a/nscd/grpcache.c
77 +++ b/nscd/grpcache.c
78 @@ -128,14 +128,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
79 }
80 else if ((dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1)) != NULL)
81 {
82 - dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
83 - dataset->head.recsize = total;
84 - dataset->head.notfound = true;
85 - dataset->head.nreloads = 0;
86 - dataset->head.usable = true;
87 -
88 - /* Compute the timeout time. */
89 - timeout = dataset->head.timeout = t + db->negtimeout;
90 + timeout = datahead_init_neg (&dataset->head,
91 + (sizeof (struct dataset)
92 + + req->key_len), total,
93 + db->negtimeout);
94
95 /* This is the reply. */
96 memcpy (&dataset->resp, &notfound, total);
97 @@ -232,14 +228,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
98 dataset_temporary = true;
99 }
100
101 - dataset->head.allocsize = total + n;
102 - dataset->head.recsize = total - offsetof (struct dataset, resp);
103 - dataset->head.notfound = false;
104 - dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
105 - dataset->head.usable = true;
106 -
107 - /* Compute the timeout time. */
108 - timeout = dataset->head.timeout = t + db->postimeout;
109 + timeout = datahead_init_pos (&dataset->head, total + n,
110 + total - offsetof (struct dataset, resp),
111 + he == NULL ? 0 : dh->nreloads + 1,
112 + db->postimeout);
113
114 dataset->resp.version = NSCD_VERSION;
115 dataset->resp.found = 1;
116 diff --git a/nscd/hstcache.c b/nscd/hstcache.c
117 index a79b67a..d4f1ad2 100644
118 --- a/nscd/hstcache.c
119 +++ b/nscd/hstcache.c
120 @@ -152,15 +152,11 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
121 else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
122 + req->key_len), 1)) != NULL)
123 {
124 - dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
125 - dataset->head.recsize = total;
126 - dataset->head.notfound = true;
127 - dataset->head.nreloads = 0;
128 - dataset->head.usable = true;
129 -
130 - /* Compute the timeout time. */
131 - dataset->head.ttl = ttl == INT32_MAX ? db->negtimeout : ttl;
132 - timeout = dataset->head.timeout = t + dataset->head.ttl;
133 + timeout = datahead_init_neg (&dataset->head,
134 + (sizeof (struct dataset)
135 + + req->key_len), total,
136 + (ttl == INT32_MAX
137 + ? db->negtimeout : ttl));
138
139 /* This is the reply. */
140 memcpy (&dataset->resp, resp, total);
141 @@ -257,15 +253,10 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
142 alloca_used = true;
143 }
144
145 - dataset->head.allocsize = total + req->key_len;
146 - dataset->head.recsize = total - offsetof (struct dataset, resp);
147 - dataset->head.notfound = false;
148 - dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
149 - dataset->head.usable = true;
150 -
151 - /* Compute the timeout time. */
152 - dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl;
153 - timeout = dataset->head.timeout = t + dataset->head.ttl;
154 + timeout = datahead_init_pos (&dataset->head, total + req->key_len,
155 + total - offsetof (struct dataset, resp),
156 + he == NULL ? 0 : dh->nreloads + 1,
157 + ttl == INT32_MAX ? db->postimeout : ttl);
158
159 dataset->resp.version = NSCD_VERSION;
160 dataset->resp.found = 1;
161 diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
162 index 1bf9f0d..361319f 100644
163 --- a/nscd/initgrcache.c
164 +++ b/nscd/initgrcache.c
165 @@ -213,14 +213,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
166 else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
167 + req->key_len), 1)) != NULL)
168 {
169 - dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
170 - dataset->head.recsize = total;
171 - dataset->head.notfound = true;
172 - dataset->head.nreloads = 0;
173 - dataset->head.usable = true;
174 -
175 - /* Compute the timeout time. */
176 - timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
177 + timeout = datahead_init_neg (&dataset->head,
178 + (sizeof (struct dataset)
179 + + req->key_len), total,
180 + db->negtimeout);
181
182 /* This is the reply. */
183 memcpy (&dataset->resp, &notfound, total);
184 @@ -276,14 +272,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
185 alloca_used = true;
186 }
187
188 - dataset->head.allocsize = total + req->key_len;
189 - dataset->head.recsize = total - offsetof (struct dataset, resp);
190 - dataset->head.notfound = false;
191 - dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
192 - dataset->head.usable = true;
193 -
194 - /* Compute the timeout time. */
195 - timeout = dataset->head.timeout = time (NULL) + db->postimeout;
196 + timeout = datahead_init_pos (&dataset->head, total + req->key_len,
197 + total - offsetof (struct dataset, resp),
198 + he == NULL ? 0 : dh->nreloads + 1,
199 + db->postimeout);
200
201 dataset->resp.version = NSCD_VERSION;
202 dataset->resp.found = 1;
203 diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
204 index 820d823..b3d40e9 100644
205 --- a/nscd/netgroupcache.c
206 +++ b/nscd/netgroupcache.c
207 @@ -90,15 +90,9 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
208 /* If we cannot permanently store the result, so be it. */
209 if (dataset != NULL)
210 {
211 - dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
212 - dataset->head.recsize = total;
213 - dataset->head.notfound = true;
214 - dataset->head.nreloads = 0;
215 - dataset->head.usable = true;
216 -
217 - /* Compute the timeout time. */
218 - timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
219 - dataset->head.ttl = db->negtimeout;
220 + timeout = datahead_init_neg (&dataset->head,
221 + sizeof (struct dataset) + req->key_len,
222 + total, db->negtimeout);
223
224 /* This is the reply. */
225 memcpy (&dataset->resp, &notfound, total);
226 @@ -359,13 +353,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
227
228 /* Fill in the dataset. */
229 dataset = (struct dataset *) buffer;
230 - dataset->head.allocsize = total + req->key_len;
231 - dataset->head.recsize = total - offsetof (struct dataset, resp);
232 - dataset->head.notfound = false;
233 - dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
234 - dataset->head.usable = true;
235 - dataset->head.ttl = db->postimeout;
236 - timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl;
237 + timeout = datahead_init_pos (&dataset->head, total + req->key_len,
238 + total - offsetof (struct dataset, resp),
239 + he == NULL ? 0 : dh->nreloads + 1,
240 + db->postimeout);
241
242 dataset->resp.version = NSCD_VERSION;
243 dataset->resp.found = 1;
244 @@ -541,12 +532,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
245 dataset = &dataset_mem;
246 }
247
248 - dataset->head.allocsize = sizeof (*dataset) + req->key_len;
249 - dataset->head.recsize = sizeof (innetgroup_response_header);
250 + datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
251 + sizeof (innetgroup_response_header),
252 + he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
253 + /* Set the notfound status and timeout based on the result from
254 + getnetgrent. */
255 dataset->head.notfound = result->head.notfound;
256 - dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
257 - dataset->head.usable = true;
258 - dataset->head.ttl = result->head.ttl;
259 dataset->head.timeout = timeout;
260
261 dataset->resp.version = NSCD_VERSION;
262 diff --git a/nscd/nscd-client.h b/nscd/nscd-client.h
263 index 98f77e7..ee16df6 100644
264 --- a/nscd/nscd-client.h
265 +++ b/nscd/nscd-client.h
266 @@ -236,6 +236,48 @@ struct datahead
267 } data[0];
268 };
269
270 +static inline time_t
271 +datahead_init_common (struct datahead *head, nscd_ssize_t allocsize,
272 + nscd_ssize_t recsize, uint32_t ttl)
273 +{
274 + /* Initialize so that we don't write out junk in uninitialized data to the
275 + cache. */
276 + memset (head, 0, sizeof (*head));
277 +
278 + head->allocsize = allocsize;
279 + head->recsize = recsize;
280 + head->usable = true;
281 +
282 + head->ttl = ttl;
283 +
284 + /* Compute and return the timeout time. */
285 + return head->timeout = time (NULL) + ttl;
286 +}
287 +
288 +static inline time_t
289 +datahead_init_pos (struct datahead *head, nscd_ssize_t allocsize,
290 + nscd_ssize_t recsize, uint8_t nreloads, uint32_t ttl)
291 +{
292 + time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
293 +
294 + head->notfound = false;
295 + head->nreloads = nreloads;
296 +
297 + return ret;
298 +}
299 +
300 +static inline time_t
301 +datahead_init_neg (struct datahead *head, nscd_ssize_t allocsize,
302 + nscd_ssize_t recsize, uint32_t ttl)
303 +{
304 + time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
305 +
306 + /* We don't need to touch nreloads here since it is set to our desired value
307 + (0) when we clear the structure. */
308 + head->notfound = true;
309 +
310 + return ret;
311 +}
312
313 /* Structure for one hash table entry. */
314 struct hashentry
315 diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
316 index fa355c3..41c245b 100644
317 --- a/nscd/pwdcache.c
318 +++ b/nscd/pwdcache.c
319 @@ -135,14 +135,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
320 else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
321 + req->key_len), 1)) != NULL)
322 {
323 - dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
324 - dataset->head.recsize = total;
325 - dataset->head.notfound = true;
326 - dataset->head.nreloads = 0;
327 - dataset->head.usable = true;
328 -
329 - /* Compute the timeout time. */
330 - timeout = dataset->head.timeout = t + db->negtimeout;
331 + timeout = datahead_init_neg (&dataset->head,
332 + (sizeof (struct dataset)
333 + + req->key_len), total,
334 + db->negtimeout);
335
336 /* This is the reply. */
337 memcpy (&dataset->resp, &notfound, total);
338 @@ -215,14 +211,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
339 alloca_used = true;
340 }
341
342 - dataset->head.allocsize = total + n;
343 - dataset->head.recsize = total - offsetof (struct dataset, resp);
344 - dataset->head.notfound = false;
345 - dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
346 - dataset->head.usable = true;
347 -
348 - /* Compute the timeout time. */
349 - timeout = dataset->head.timeout = t + db->postimeout;
350 + timeout = datahead_init_pos (&dataset->head, total + n,
351 + total - offsetof (struct dataset, resp),
352 + he == NULL ? 0 : dh->nreloads + 1,
353 + db->postimeout);
354
355 dataset->resp.version = NSCD_VERSION;
356 dataset->resp.found = 1;
357 diff --git a/nscd/servicescache.c b/nscd/servicescache.c
358 index 12ce9b2..95bdcfe 100644
359 --- a/nscd/servicescache.c
360 +++ b/nscd/servicescache.c
361 @@ -120,14 +120,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
362 else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
363 + req->key_len), 1)) != NULL)
364 {
365 - dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
366 - dataset->head.recsize = total;
367 - dataset->head.notfound = true;
368 - dataset->head.nreloads = 0;
369 - dataset->head.usable = true;
370 -
371 - /* Compute the timeout time. */
372 - timeout = dataset->head.timeout = t + db->negtimeout;
373 + timeout = datahead_init_neg (&dataset->head,
374 + (sizeof (struct dataset)
375 + + req->key_len), total,
376 + db->negtimeout);
377
378 /* This is the reply. */
379 memcpy (&dataset->resp, &notfound, total);
380 @@ -207,14 +203,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
381 alloca_used = true;
382 }
383
384 - dataset->head.allocsize = total + req->key_len;
385 - dataset->head.recsize = total - offsetof (struct dataset, resp);
386 - dataset->head.notfound = false;
387 - dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
388 - dataset->head.usable = true;
389 -
390 - /* Compute the timeout time. */
391 - timeout = dataset->head.timeout = t + db->postimeout;
392 + timeout = datahead_init_pos (&dataset->head, total + req->key_len,
393 + total - offsetof (struct dataset, resp),
394 + he == NULL ? 0 : dh->nreloads + 1,
395 + db->postimeout);
396
397 dataset->resp.version = NSCD_VERSION;
398 dataset->resp.found = 1;