Smack: add the execute lable to ldconfig
[platform/upstream/glibc.git] / nscd / hstcache.c
1 /* Cache handling for host lookup.
2    Copyright (C) 1998-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published
8    by the Free Software Foundation; version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, see <http://www.gnu.org/licenses/>.  */
18
19 #include <alloca.h>
20 #include <assert.h>
21 #include <errno.h>
22 #include <error.h>
23 #include <libintl.h>
24 #include <netdb.h>
25 #include <stdbool.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <time.h>
31 #include <unistd.h>
32 #include <stdint.h>
33 #include <arpa/inet.h>
34 #include <arpa/nameser.h>
35 #include <sys/mman.h>
36 #include <stackinfo.h>
37
38 #include "nscd.h"
39 #include "dbg_log.h"
40 #ifdef HAVE_SENDFILE
41 # include <kernel-features.h>
42 #endif
43
44
45 /* This is the standard reply in case the service is disabled.  */
46 static const hst_response_header disabled =
47 {
48   .version = NSCD_VERSION,
49   .found = -1,
50   .h_name_len = 0,
51   .h_aliases_cnt = 0,
52   .h_addrtype = -1,
53   .h_length = -1,
54   .h_addr_list_cnt = 0,
55   .error = NETDB_INTERNAL
56 };
57
58 /* This is the struct describing how to write this record.  */
59 const struct iovec hst_iov_disabled =
60 {
61   .iov_base = (void *) &disabled,
62   .iov_len = sizeof (disabled)
63 };
64
65
66 /* This is the standard reply in case we haven't found the dataset.  */
67 static const hst_response_header notfound =
68 {
69   .version = NSCD_VERSION,
70   .found = 0,
71   .h_name_len = 0,
72   .h_aliases_cnt = 0,
73   .h_addrtype = -1,
74   .h_length = -1,
75   .h_addr_list_cnt = 0,
76   .error = HOST_NOT_FOUND
77 };
78
79
80 /* This is the standard reply in case there are temporary problems.  */
81 static const hst_response_header tryagain =
82 {
83   .version = NSCD_VERSION,
84   .found = 0,
85   .h_name_len = 0,
86   .h_aliases_cnt = 0,
87   .h_addrtype = -1,
88   .h_length = -1,
89   .h_addr_list_cnt = 0,
90   .error = TRY_AGAIN
91 };
92
93
94 static time_t
95 cache_addhst (struct database_dyn *db, int fd, request_header *req,
96               const void *key, struct hostent *hst, uid_t owner,
97               struct hashentry *const he, struct datahead *dh, int errval,
98               int32_t ttl)
99 {
100   bool all_written = true;
101   time_t t = time (NULL);
102
103   /* We allocate all data in one memory block: the iov vector,
104      the response header and the dataset itself.  */
105   struct dataset
106   {
107     struct datahead head;
108     hst_response_header resp;
109     char strdata[0];
110   } *dataset;
111
112   assert (offsetof (struct dataset, resp) == offsetof (struct datahead, data));
113
114   time_t timeout = MAX_TIMEOUT_VALUE;
115   if (hst == NULL)
116     {
117       if (he != NULL && errval == EAGAIN)
118         {
119           /* If we have an old record available but cannot find one
120              now because the service is not available we keep the old
121              record and make sure it does not get removed.  */
122           if (reload_count != UINT_MAX)
123             /* Do not reset the value if we never not reload the record.  */
124             dh->nreloads = reload_count - 1;
125
126           /* Reload with the same time-to-live value.  */
127           timeout = dh->timeout = t + dh->ttl;
128         }
129       else
130         {
131           /* We have no data.  This means we send the standard reply for this
132              case.  Possibly this is only temporary.  */
133           ssize_t total = sizeof (notfound);
134           assert (sizeof (notfound) == sizeof (tryagain));
135
136           const hst_response_header *resp = (errval == EAGAIN
137                                              ? &tryagain : &notfound);
138
139           if (fd != -1 &&
140               TEMP_FAILURE_RETRY (send (fd, resp, total,
141                                         MSG_NOSIGNAL)) != total)
142             all_written = false;
143
144           /* If we have a transient error or cannot permanently store
145              the result, so be it.  */
146           if (errval == EAGAIN || __builtin_expect (db->negtimeout == 0, 0))
147             {
148               /* Mark the old entry as obsolete.  */
149               if (dh != NULL)
150                 dh->usable = false;
151             }
152           else if ((dataset = mempool_alloc (db, (sizeof (struct dataset)
153                                                   + req->key_len), 1)) != NULL)
154             {
155               timeout = datahead_init_neg (&dataset->head,
156                                            (sizeof (struct dataset)
157                                             + req->key_len), total,
158                                            (ttl == INT32_MAX
159                                             ? db->negtimeout : ttl));
160
161               /* This is the reply.  */
162               memcpy (&dataset->resp, resp, total);
163
164               /* Copy the key data.  */
165               memcpy (dataset->strdata, key, req->key_len);
166
167               /* If necessary, we also propagate the data to disk.  */
168               if (db->persistent)
169                 {
170                   // XXX async OK?
171                   uintptr_t pval = (uintptr_t) dataset & ~pagesize_m1;
172                   msync ((void *) pval,
173                          ((uintptr_t) dataset & pagesize_m1)
174                          + sizeof (struct dataset) + req->key_len, MS_ASYNC);
175                 }
176
177               (void) cache_add (req->type, &dataset->strdata, req->key_len,
178                                 &dataset->head, true, db, owner, he == NULL);
179
180               pthread_rwlock_unlock (&db->lock);
181
182               /* Mark the old entry as obsolete.  */
183               if (dh != NULL)
184                 dh->usable = false;
185             }
186         }
187     }
188   else
189     {
190       /* Determine the I/O structure.  */
191       size_t h_name_len = strlen (hst->h_name) + 1;
192       size_t h_aliases_cnt;
193       uint32_t *h_aliases_len;
194       size_t h_addr_list_cnt;
195       char *addresses;
196       char *aliases;
197       char *key_copy = NULL;
198       char *cp;
199       size_t cnt;
200       ssize_t total;
201
202       /* Determine the number of aliases.  */
203       h_aliases_cnt = 0;
204       for (cnt = 0; hst->h_aliases[cnt] != NULL; ++cnt)
205         ++h_aliases_cnt;
206       /* Determine the length of all aliases.  */
207       h_aliases_len = (uint32_t *) alloca (h_aliases_cnt * sizeof (uint32_t));
208       total = 0;
209       for (cnt = 0; cnt < h_aliases_cnt; ++cnt)
210         {
211           h_aliases_len[cnt] = strlen (hst->h_aliases[cnt]) + 1;
212           total += h_aliases_len[cnt];
213         }
214
215       /* Determine the number of addresses.  */
216       h_addr_list_cnt = 0;
217       while (hst->h_addr_list[h_addr_list_cnt] != NULL)
218         ++h_addr_list_cnt;
219
220       if (h_addr_list_cnt == 0)
221         /* Invalid entry.  */
222         return MAX_TIMEOUT_VALUE;
223
224       total += (sizeof (struct dataset)
225                 + h_name_len
226                 + h_aliases_cnt * sizeof (uint32_t)
227                 + h_addr_list_cnt * hst->h_length);
228
229       /* If we refill the cache, first assume the reconrd did not
230          change.  Allocate memory on the cache since it is likely
231          discarded anyway.  If it turns out to be necessary to have a
232          new record we can still allocate real memory.  */
233       bool alloca_used = false;
234       dataset = NULL;
235
236       /* If the record contains more than one IP address (used for
237          load balancing etc) don't cache the entry.  This is something
238          the current cache handling cannot handle and it is more than
239          questionable whether it is worthwhile complicating the cache
240          handling just for handling such a special case. */
241       if (he == NULL && h_addr_list_cnt == 1)
242         dataset = (struct dataset *) mempool_alloc (db, total + req->key_len,
243                                                     1);
244
245       if (dataset == NULL)
246         {
247           /* We cannot permanently add the result in the moment.  But
248              we can provide the result as is.  Store the data in some
249              temporary memory.  */
250           dataset = (struct dataset *) alloca (total + req->key_len);
251
252           /* We cannot add this record to the permanent database.  */
253           alloca_used = true;
254         }
255
256       timeout = datahead_init_pos (&dataset->head, total + req->key_len,
257                                    total - offsetof (struct dataset, resp),
258                                    he == NULL ? 0 : dh->nreloads + 1,
259                                    ttl == INT32_MAX ? db->postimeout : ttl);
260
261       dataset->resp.version = NSCD_VERSION;
262       dataset->resp.found = 1;
263       dataset->resp.h_name_len = h_name_len;
264       dataset->resp.h_aliases_cnt = h_aliases_cnt;
265       dataset->resp.h_addrtype = hst->h_addrtype;
266       dataset->resp.h_length = hst->h_length;
267       dataset->resp.h_addr_list_cnt = h_addr_list_cnt;
268       dataset->resp.error = NETDB_SUCCESS;
269
270       /* Make sure there is no gap.  */
271       assert ((char *) (&dataset->resp.error + 1) == dataset->strdata);
272
273       cp = dataset->strdata;
274
275       cp = mempcpy (cp, hst->h_name, h_name_len);
276       cp = mempcpy (cp, h_aliases_len, h_aliases_cnt * sizeof (uint32_t));
277
278       /* The normal addresses first.  */
279       addresses = cp;
280       for (cnt = 0; cnt < h_addr_list_cnt; ++cnt)
281         cp = mempcpy (cp, hst->h_addr_list[cnt], hst->h_length);
282
283       /* Then the aliases.  */
284       aliases = cp;
285       for (cnt = 0; cnt < h_aliases_cnt; ++cnt)
286         cp = mempcpy (cp, hst->h_aliases[cnt], h_aliases_len[cnt]);
287
288       assert (cp
289               == dataset->strdata + total - offsetof (struct dataset,
290                                                       strdata));
291
292       /* If we are adding a GETHOSTBYNAME{,v6} entry we must be prepared
293          that the answer we get from the NSS does not contain the key
294          itself.  This is the case if the resolver is used and the name
295          is extended by the domainnames from /etc/resolv.conf.  Therefore
296          we explicitly add the name here.  */
297       key_copy = memcpy (cp, key, req->key_len);
298
299       assert ((char *) &dataset->resp + dataset->head.recsize == cp);
300
301       /* Now we can determine whether on refill we have to create a new
302          record or not.  */
303       if (he != NULL)
304         {
305           assert (fd == -1);
306
307           if (total + req->key_len == dh->allocsize
308               && total - offsetof (struct dataset, resp) == dh->recsize
309               && memcmp (&dataset->resp, dh->data,
310                          dh->allocsize - offsetof (struct dataset, resp)) == 0)
311             {
312               /* The data has not changed.  We will just bump the
313                  timeout value.  Note that the new record has been
314                  allocated on the stack and need not be freed.  */
315               assert (h_addr_list_cnt == 1);
316               dh->ttl = dataset->head.ttl;
317               dh->timeout = dataset->head.timeout;
318               ++dh->nreloads;
319             }
320           else
321             {
322               if (h_addr_list_cnt == 1)
323                 {
324                   /* We have to create a new record.  Just allocate
325                      appropriate memory and copy it.  */
326                   struct dataset *newp
327                     = (struct dataset *) mempool_alloc (db,
328                                                         total + req->key_len,
329                                                         1);
330                   if (newp != NULL)
331                     {
332                       /* Adjust pointers into the memory block.  */
333                       addresses = (char *) newp + (addresses
334                                                    - (char *) dataset);
335                       aliases = (char *) newp + (aliases - (char *) dataset);
336                       assert (key_copy != NULL);
337                       key_copy = (char *) newp + (key_copy - (char *) dataset);
338
339                       dataset = memcpy (newp, dataset, total + req->key_len);
340                       alloca_used = false;
341                     }
342                 }
343
344               /* Mark the old record as obsolete.  */
345               dh->usable = false;
346             }
347         }
348       else
349         {
350           /* We write the dataset before inserting it to the database
351              since while inserting this thread might block and so would
352              unnecessarily keep the receiver waiting.  */
353           assert (fd != -1);
354
355 #ifdef HAVE_SENDFILE
356           if (__builtin_expect (db->mmap_used, 1) && !alloca_used)
357             {
358               assert (db->wr_fd != -1);
359               assert ((char *) &dataset->resp > (char *) db->data);
360               assert ((char *) dataset - (char *) db->head
361                       + total
362                       <= (sizeof (struct database_pers_head)
363                           + db->head->module * sizeof (ref_t)
364                           + db->head->data_size));
365               ssize_t written = sendfileall (fd, db->wr_fd,
366                                              (char *) &dataset->resp
367                                              - (char *) db->head,
368                                              dataset->head.recsize);
369               if (written != dataset->head.recsize)
370                 {
371 # ifndef __ASSUME_SENDFILE
372                   if (written == -1 && errno == ENOSYS)
373                     goto use_write;
374 # endif
375                   all_written = false;
376                 }
377             }
378           else
379 # ifndef __ASSUME_SENDFILE
380           use_write:
381 # endif
382 #endif
383             if (writeall (fd, &dataset->resp, dataset->head.recsize)
384                 != dataset->head.recsize)
385               all_written = false;
386         }
387
388       /* Add the record to the database.  But only if it has not been
389          stored on the stack.
390
391          If the record contains more than one IP address (used for
392          load balancing etc) don't cache the entry.  This is something
393          the current cache handling cannot handle and it is more than
394          questionable whether it is worthwhile complicating the cache
395          handling just for handling such a special case. */
396       if (! alloca_used)
397         {
398           /* If necessary, we also propagate the data to disk.  */
399           if (db->persistent)
400             {
401               // XXX async OK?
402               uintptr_t pval = (uintptr_t) dataset & ~pagesize_m1;
403               msync ((void *) pval,
404                      ((uintptr_t) dataset & pagesize_m1)
405                      + total + req->key_len, MS_ASYNC);
406             }
407
408           /* NB: the following code is really complicated.  It has
409              seemlingly duplicated code paths which do the same.  The
410              problem is that we always must add the hash table entry
411              with the FIRST flag set first.  Otherwise we get dangling
412              pointers in case memory allocation fails.  */
413           assert (hst->h_addr_list[1] == NULL);
414
415           /* Avoid adding names if more than one address is available.  See
416              above for more info.  */
417           assert (req->type == GETHOSTBYNAME
418                   || req->type == GETHOSTBYNAMEv6
419                   || req->type == GETHOSTBYADDR
420                   || req->type == GETHOSTBYADDRv6);
421
422           (void) cache_add (req->type, key_copy, req->key_len,
423                             &dataset->head, true, db, owner, he == NULL);
424
425           pthread_rwlock_unlock (&db->lock);
426         }
427     }
428
429   if (__builtin_expect (!all_written, 0) && debug_level > 0)
430     {
431       char buf[256];
432       dbg_log (_("short write in %s: %s"),  __FUNCTION__,
433                strerror_r (errno, buf, sizeof (buf)));
434     }
435
436   return timeout;
437 }
438
439
440 static int
441 lookup (int type, void *key, struct hostent *resultbufp, char *buffer,
442         size_t buflen, struct hostent **hst, int32_t *ttlp)
443 {
444   if (type == GETHOSTBYNAME)
445     return __gethostbyname3_r (key, AF_INET, resultbufp, buffer, buflen, hst,
446                                &h_errno, ttlp, NULL);
447   if (type == GETHOSTBYNAMEv6)
448     return __gethostbyname3_r (key, AF_INET6, resultbufp, buffer, buflen, hst,
449                                &h_errno, ttlp, NULL);
450   if (type == GETHOSTBYADDR)
451     return __gethostbyaddr2_r (key, NS_INADDRSZ, AF_INET, resultbufp, buffer,
452                                buflen, hst, &h_errno, ttlp);
453   return __gethostbyaddr2_r (key, NS_IN6ADDRSZ, AF_INET6, resultbufp, buffer,
454                              buflen, hst, &h_errno, ttlp);
455 }
456
457
458 static time_t
459 addhstbyX (struct database_dyn *db, int fd, request_header *req,
460            void *key, uid_t uid, struct hashentry *he, struct datahead *dh)
461 {
462   /* Search for the entry matching the key.  Please note that we don't
463      look again in the table whether the dataset is now available.  We
464      simply insert it.  It does not matter if it is in there twice.  The
465      pruning function only will look at the timestamp.  */
466   int buflen = 1024;
467   char *buffer = (char *) alloca (buflen);
468   struct hostent resultbuf;
469   struct hostent *hst;
470   bool use_malloc = false;
471   int errval = 0;
472   int32_t ttl = INT32_MAX;
473
474   if (__glibc_unlikely (debug_level > 0))
475     {
476       const char *str;
477       char buf[INET6_ADDRSTRLEN + 1];
478       if (req->type == GETHOSTBYNAME || req->type == GETHOSTBYNAMEv6)
479         str = key;
480       else
481         str = inet_ntop (req->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
482                          key, buf, sizeof (buf));
483
484       if (he == NULL)
485         dbg_log (_("Haven't found \"%s\" in hosts cache!"), (char *) str);
486       else
487         dbg_log (_("Reloading \"%s\" in hosts cache!"), (char *) str);
488     }
489
490   while (lookup (req->type, key, &resultbuf, buffer, buflen, &hst, &ttl) != 0
491          && h_errno == NETDB_INTERNAL
492          && (errval = errno) == ERANGE)
493     {
494       errno = 0;
495
496       if (__glibc_unlikely (buflen > 32768))
497         {
498           char *old_buffer = buffer;
499           buflen *= 2;
500           buffer = (char *) realloc (use_malloc ? buffer : NULL, buflen);
501           if (buffer == NULL)
502             {
503               /* We ran out of memory.  We cannot do anything but
504                  sending a negative response.  In reality this should
505                  never happen.  */
506               hst = NULL;
507               buffer = old_buffer;
508
509               /* We set the error to indicate this is (possibly) a
510                  temporary error and that it does not mean the entry
511                  is not available at all.  */
512               h_errno = TRY_AGAIN;
513               errval = EAGAIN;
514               break;
515             }
516           use_malloc = true;
517         }
518       else
519         /* Allocate a new buffer on the stack.  If possible combine it
520            with the previously allocated buffer.  */
521         buffer = (char *) extend_alloca (buffer, buflen, 2 * buflen);
522     }
523
524   time_t timeout = cache_addhst (db, fd, req, key, hst, uid, he, dh,
525                                  h_errno == TRY_AGAIN ? errval : 0, ttl);
526
527   if (use_malloc)
528     free (buffer);
529
530   return timeout;
531 }
532
533
534 void
535 addhstbyname (struct database_dyn *db, int fd, request_header *req,
536               void *key, uid_t uid)
537 {
538   addhstbyX (db, fd, req, key, uid, NULL, NULL);
539 }
540
541
542 time_t
543 readdhstbyname (struct database_dyn *db, struct hashentry *he,
544                 struct datahead *dh)
545 {
546   request_header req =
547     {
548       .type = GETHOSTBYNAME,
549       .key_len = he->len
550     };
551
552   return addhstbyX (db, -1, &req, db->data + he->key, he->owner, he, dh);
553 }
554
555
556 void
557 addhstbyaddr (struct database_dyn *db, int fd, request_header *req,
558               void *key, uid_t uid)
559 {
560   addhstbyX (db, fd, req, key, uid, NULL, NULL);
561 }
562
563
564 time_t
565 readdhstbyaddr (struct database_dyn *db, struct hashentry *he,
566                 struct datahead *dh)
567 {
568   request_header req =
569     {
570       .type = GETHOSTBYADDR,
571       .key_len = he->len
572     };
573
574   return addhstbyX (db, -1, &req, db->data + he->key, he->owner, he, dh);
575 }
576
577
578 void
579 addhstbynamev6 (struct database_dyn *db, int fd, request_header *req,
580                 void *key, uid_t uid)
581 {
582   addhstbyX (db, fd, req, key, uid, NULL, NULL);
583 }
584
585
586 time_t
587 readdhstbynamev6 (struct database_dyn *db, struct hashentry *he,
588                   struct datahead *dh)
589 {
590   request_header req =
591     {
592       .type = GETHOSTBYNAMEv6,
593       .key_len = he->len
594     };
595
596   return addhstbyX (db, -1, &req, db->data + he->key, he->owner, he, dh);
597 }
598
599
600 void
601 addhstbyaddrv6 (struct database_dyn *db, int fd, request_header *req,
602                 void *key, uid_t uid)
603 {
604   addhstbyX (db, fd, req, key, uid, NULL, NULL);
605 }
606
607
608 time_t
609 readdhstbyaddrv6 (struct database_dyn *db, struct hashentry *he,
610                   struct datahead *dh)
611 {
612   request_header req =
613     {
614       .type = GETHOSTBYADDRv6,
615       .key_len = he->len
616     };
617
618   return addhstbyX (db, -1, &req, db->data + he->key, he->owner, he, dh);
619 }