1 commit bc8f194c8c29e46e8ee4034f06e46988dfff38f7
2 Author: Siddhesh Poyarekar <siddhesh@redhat.com>
3 Date: Wed Apr 30 12:00:39 2014 +0530
5 Initialize all of datahead structure in nscd (BZ #16791)
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.
14 commit 1cdeb2372ddecac0dfe0c132a033e9590ffa07d2
15 Author: Siddhesh Poyarekar <siddhesh@redhat.com>
16 Date: Wed Apr 30 11:57:09 2014 +0530
18 Consolidate code to initialize nscd dataset header
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
28 diff --git a/nscd/aicache.c b/nscd/aicache.c
29 index 98d40a1..d7966bd 100644
32 @@ -383,17 +383,12 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
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;
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);
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)
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;
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);
72 /* This is the reply. */
73 memcpy (&dataset->resp, ¬found, total);
74 diff --git a/nscd/grpcache.c b/nscd/grpcache.c
75 index b5a33eb..df59fa7 100644
78 @@ -128,14 +128,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
80 else if ((dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1)) != NULL)
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;
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,
95 /* This is the reply. */
96 memcpy (&dataset->resp, ¬found, total);
97 @@ -232,14 +228,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
98 dataset_temporary = true;
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;
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,
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)
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;
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,
137 + ? db->negtimeout : ttl));
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,
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;
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);
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)
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;
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,
182 /* This is the reply. */
183 memcpy (&dataset->resp, ¬found, total);
184 @@ -276,14 +272,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
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;
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,
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. */
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;
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);
224 /* This is the reply. */
225 memcpy (&dataset->resp, ¬found, total);
226 @@ -359,13 +353,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
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,
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;
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
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;
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
270 +static inline time_t
271 +datahead_init_common (struct datahead *head, nscd_ssize_t allocsize,
272 + nscd_ssize_t recsize, uint32_t ttl)
274 + /* Initialize so that we don't write out junk in uninitialized data to the
276 + memset (head, 0, sizeof (*head));
278 + head->allocsize = allocsize;
279 + head->recsize = recsize;
280 + head->usable = true;
284 + /* Compute and return the timeout time. */
285 + return head->timeout = time (NULL) + ttl;
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)
292 + time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
294 + head->notfound = false;
295 + head->nreloads = nreloads;
300 +static inline time_t
301 +datahead_init_neg (struct datahead *head, nscd_ssize_t allocsize,
302 + nscd_ssize_t recsize, uint32_t ttl)
304 + time_t ret = datahead_init_common (head, allocsize, recsize, ttl);
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;
313 /* Structure for one hash table entry. */
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)
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;
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,
336 /* This is the reply. */
337 memcpy (&dataset->resp, ¬found, total);
338 @@ -215,14 +211,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
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;
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,
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)
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;
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,
378 /* This is the reply. */
379 memcpy (&dataset->resp, ¬found, total);
380 @@ -207,14 +203,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
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;
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,
397 dataset->resp.version = NSCD_VERSION;
398 dataset->resp.found = 1;