Mark internal time functions with attribute_hidden [BZ #18822]
[glibc.git] / nscd / nscd_helper.c
bloba225623f9273832fd66e74760c04f8f89f2ac40e
1 /* Copyright (C) 1998-2017 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <assert.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <stdbool.h>
23 #include <stddef.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include <stdint.h>
29 #include <sys/mman.h>
30 #include <sys/poll.h>
31 #include <sys/socket.h>
32 #include <sys/stat.h>
33 #include <sys/time.h>
34 #include <sys/uio.h>
35 #include <sys/un.h>
36 #include <not-cancel.h>
37 #include <nis/rpcsvc/nis.h>
38 #include <kernel-features.h>
40 #include "nscd-client.h"
43 /* Extra time we wait if the socket is still receiving data. This
44 value is in milliseconds. Note that the other side is nscd on the
45 local machine and it is already transmitting data. So the wait
46 time need not be long. */
47 #define EXTRA_RECEIVE_TIME 200
50 static int
51 wait_on_socket (int sock, long int usectmo)
53 struct pollfd fds[1];
54 fds[0].fd = sock;
55 fds[0].events = POLLIN | POLLERR | POLLHUP;
56 int n = __poll (fds, 1, usectmo);
57 if (n == -1 && __builtin_expect (errno == EINTR, 0))
59 /* Handle the case where the poll() call is interrupted by a
60 signal. We cannot just use TEMP_FAILURE_RETRY since it might
61 lead to infinite loops. */
62 struct timeval now;
63 (void) __gettimeofday (&now, NULL);
64 long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec + 500) / 1000;
65 long int timeout = usectmo;
66 while (1)
68 n = __poll (fds, 1, timeout);
69 if (n != -1 || errno != EINTR)
70 break;
72 /* Recompute the timeout time. */
73 (void) __gettimeofday (&now, NULL);
74 timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000);
78 return n;
82 ssize_t
83 __readall (int fd, void *buf, size_t len)
85 size_t n = len;
86 ssize_t ret;
89 again:
90 ret = TEMP_FAILURE_RETRY (__read (fd, buf, n));
91 if (ret <= 0)
93 if (__builtin_expect (ret < 0 && errno == EAGAIN, 0)
94 /* The socket is still receiving data. Wait a bit more. */
95 && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0)
96 goto again;
98 break;
100 buf = (char *) buf + ret;
101 n -= ret;
103 while (n > 0);
104 return ret < 0 ? ret : len - n;
108 ssize_t
109 __readvall (int fd, const struct iovec *iov, int iovcnt)
111 ssize_t ret = TEMP_FAILURE_RETRY (__readv (fd, iov, iovcnt));
112 if (ret <= 0)
114 if (__glibc_likely (ret == 0 || errno != EAGAIN))
115 /* A genuine error or no data to read. */
116 return ret;
118 /* The data has not all yet been received. Do as if we have not
119 read anything yet. */
120 ret = 0;
123 size_t total = 0;
124 for (int i = 0; i < iovcnt; ++i)
125 total += iov[i].iov_len;
127 if (ret < total)
129 struct iovec iov_buf[iovcnt];
130 ssize_t r = ret;
132 struct iovec *iovp = memcpy (iov_buf, iov, iovcnt * sizeof (*iov));
135 while (iovp->iov_len <= r)
137 r -= iovp->iov_len;
138 --iovcnt;
139 ++iovp;
141 iovp->iov_base = (char *) iovp->iov_base + r;
142 iovp->iov_len -= r;
143 again:
144 r = TEMP_FAILURE_RETRY (__readv (fd, iovp, iovcnt));
145 if (r <= 0)
147 if (__builtin_expect (r < 0 && errno == EAGAIN, 0)
148 /* The socket is still receiving data. Wait a bit more. */
149 && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0)
150 goto again;
152 break;
154 ret += r;
156 while (ret < total);
157 if (r < 0)
158 ret = r;
160 return ret;
164 static int
165 open_socket (request_type type, const char *key, size_t keylen)
167 int sock;
169 sock = __socket (PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
170 if (sock < 0)
171 return -1;
173 size_t real_sizeof_reqdata = sizeof (request_header) + keylen;
174 struct
176 request_header req;
177 char key[];
178 } *reqdata = alloca (real_sizeof_reqdata);
180 struct sockaddr_un sun;
181 sun.sun_family = AF_UNIX;
182 strcpy (sun.sun_path, _PATH_NSCDSOCKET);
183 if (__connect (sock, (struct sockaddr *) &sun, sizeof (sun)) < 0
184 && errno != EINPROGRESS)
185 goto out;
187 reqdata->req.version = NSCD_VERSION;
188 reqdata->req.type = type;
189 reqdata->req.key_len = keylen;
191 memcpy (reqdata->key, key, keylen);
193 bool first_try = true;
194 struct timeval tvend;
195 /* Fake initializing tvend. */
196 asm ("" : "=m" (tvend));
197 while (1)
199 #ifndef MSG_NOSIGNAL
200 # define MSG_NOSIGNAL 0
201 #endif
202 ssize_t wres = TEMP_FAILURE_RETRY (__send (sock, reqdata,
203 real_sizeof_reqdata,
204 MSG_NOSIGNAL));
205 if (__glibc_likely (wres == (ssize_t) real_sizeof_reqdata))
206 /* We managed to send the request. */
207 return sock;
209 if (wres != -1 || errno != EAGAIN)
210 /* Something is really wrong, no chance to continue. */
211 break;
213 /* The daemon is busy wait for it. */
214 int to;
215 struct timeval now;
216 (void) __gettimeofday (&now, NULL);
217 if (first_try)
219 tvend.tv_usec = now.tv_usec;
220 tvend.tv_sec = now.tv_sec + 5;
221 to = 5 * 1000;
222 first_try = false;
224 else
225 to = ((tvend.tv_sec - now.tv_sec) * 1000
226 + (tvend.tv_usec - now.tv_usec) / 1000);
228 struct pollfd fds[1];
229 fds[0].fd = sock;
230 fds[0].events = POLLOUT | POLLERR | POLLHUP;
231 if (__poll (fds, 1, to) <= 0)
232 /* The connection timed out or broke down. */
233 break;
235 /* We try to write again. */
238 out:
239 __close_nocancel_nostatus (sock);
241 return -1;
245 void
246 __nscd_unmap (struct mapped_database *mapped)
248 assert (mapped->counter == 0);
249 __munmap ((void *) mapped->head, mapped->mapsize);
250 free (mapped);
254 /* Try to get a file descriptor for the shared meory segment
255 containing the database. */
256 struct mapped_database *
257 __nscd_get_mapping (request_type type, const char *key,
258 struct mapped_database **mappedp)
260 struct mapped_database *result = NO_MAPPING;
261 #ifdef SCM_RIGHTS
262 const size_t keylen = strlen (key) + 1;
263 int saved_errno = errno;
265 int mapfd = -1;
266 char resdata[keylen];
268 /* Open a socket and send the request. */
269 int sock = open_socket (type, key, keylen);
270 if (sock < 0)
271 goto out;
273 /* Room for the data sent along with the file descriptor. We expect
274 the key name back. */
275 uint64_t mapsize;
276 struct iovec iov[2];
277 iov[0].iov_base = resdata;
278 iov[0].iov_len = keylen;
279 iov[1].iov_base = &mapsize;
280 iov[1].iov_len = sizeof (mapsize);
282 union
284 struct cmsghdr hdr;
285 char bytes[CMSG_SPACE (sizeof (int))];
286 } buf;
287 struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 2,
288 .msg_control = buf.bytes,
289 .msg_controllen = sizeof (buf) };
290 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
292 cmsg->cmsg_level = SOL_SOCKET;
293 cmsg->cmsg_type = SCM_RIGHTS;
294 cmsg->cmsg_len = CMSG_LEN (sizeof (int));
296 /* This access is well-aligned since BUF is correctly aligned for an
297 int and CMSG_DATA preserves this alignment. */
298 memset (CMSG_DATA (cmsg), '\xff', sizeof (int));
300 msg.msg_controllen = cmsg->cmsg_len;
302 if (wait_on_socket (sock, 5 * 1000) <= 0)
303 goto out_close2;
305 # ifndef MSG_CMSG_CLOEXEC
306 # define MSG_CMSG_CLOEXEC 0
307 # endif
308 ssize_t n = TEMP_FAILURE_RETRY (__recvmsg (sock, &msg, MSG_CMSG_CLOEXEC));
310 if (__builtin_expect (CMSG_FIRSTHDR (&msg) == NULL
311 || (CMSG_FIRSTHDR (&msg)->cmsg_len
312 != CMSG_LEN (sizeof (int))), 0))
313 goto out_close2;
315 int *ip = (void *) CMSG_DATA (cmsg);
316 mapfd = *ip;
318 if (__glibc_unlikely (n != keylen && n != keylen + sizeof (mapsize)))
319 goto out_close;
321 if (__glibc_unlikely (strcmp (resdata, key) != 0))
322 goto out_close;
324 if (__glibc_unlikely (n == keylen))
326 struct stat64 st;
327 if (__builtin_expect (fstat64 (mapfd, &st) != 0, 0)
328 || __builtin_expect (st.st_size < sizeof (struct database_pers_head),
330 goto out_close;
332 mapsize = st.st_size;
335 /* The file is large enough, map it now. */
336 void *mapping = __mmap (NULL, mapsize, PROT_READ, MAP_SHARED, mapfd, 0);
337 if (__glibc_likely (mapping != MAP_FAILED))
339 /* Check whether the database is correct and up-to-date. */
340 struct database_pers_head *head = mapping;
342 if (__builtin_expect (head->version != DB_VERSION, 0)
343 || __builtin_expect (head->header_size != sizeof (*head), 0)
344 /* Catch some misconfiguration. The server should catch
345 them now but some older versions did not. */
346 || __builtin_expect (head->module == 0, 0)
347 /* This really should not happen but who knows, maybe the update
348 thread got stuck. */
349 || __builtin_expect (! head->nscd_certainly_running
350 && (head->timestamp + MAPPING_TIMEOUT
351 < time (NULL)), 0))
353 out_unmap:
354 __munmap (mapping, mapsize);
355 goto out_close;
358 size_t size = (sizeof (*head) + roundup (head->module * sizeof (ref_t),
359 ALIGN)
360 + head->data_size);
362 if (__glibc_unlikely (mapsize < size))
363 goto out_unmap;
365 /* Allocate a record for the mapping. */
366 struct mapped_database *newp = malloc (sizeof (*newp));
367 if (newp == NULL)
368 /* Ugh, after all we went through the memory allocation failed. */
369 goto out_unmap;
371 newp->head = mapping;
372 newp->data = ((char *) mapping + head->header_size
373 + roundup (head->module * sizeof (ref_t), ALIGN));
374 newp->mapsize = size;
375 newp->datasize = head->data_size;
376 /* Set counter to 1 to show it is usable. */
377 newp->counter = 1;
379 result = newp;
382 out_close:
383 __close (mapfd);
384 out_close2:
385 __close (sock);
386 out:
387 __set_errno (saved_errno);
388 #endif /* SCM_RIGHTS */
390 struct mapped_database *oldval = *mappedp;
391 *mappedp = result;
393 if (oldval != NULL && atomic_decrement_val (&oldval->counter) == 0)
394 __nscd_unmap (oldval);
396 return result;
399 struct mapped_database *
400 __nscd_get_map_ref (request_type type, const char *name,
401 volatile struct locked_map_ptr *mapptr, int *gc_cyclep)
403 struct mapped_database *cur = mapptr->mapped;
404 if (cur == NO_MAPPING)
405 return cur;
407 if (!__nscd_acquire_maplock (mapptr))
408 return NO_MAPPING;
410 cur = mapptr->mapped;
412 if (__glibc_likely (cur != NO_MAPPING))
414 /* If not mapped or timestamp not updated, request new map. */
415 if (cur == NULL
416 || (cur->head->nscd_certainly_running == 0
417 && cur->head->timestamp + MAPPING_TIMEOUT < time (NULL))
418 || cur->head->data_size > cur->datasize)
419 cur = __nscd_get_mapping (type, name,
420 (struct mapped_database **) &mapptr->mapped);
422 if (__glibc_likely (cur != NO_MAPPING))
424 if (__builtin_expect (((*gc_cyclep = cur->head->gc_cycle) & 1) != 0,
426 cur = NO_MAPPING;
427 else
428 atomic_increment (&cur->counter);
432 mapptr->lock = 0;
434 return cur;
438 /* Using sizeof (hashentry) is not always correct to determine the size of
439 the data structure as found in the nscd cache. The program could be
440 a 64-bit process and nscd could be a 32-bit process. In this case
441 sizeof (hashentry) would overestimate the size. The following is
442 the minimum size of such an entry, good enough for our tests here. */
443 #define MINIMUM_HASHENTRY_SIZE \
444 (offsetof (struct hashentry, dellist) + sizeof (int32_t))
447 /* Don't return const struct datahead *, as eventhough the record
448 is normally constant, it can change arbitrarily during nscd
449 garbage collection. */
450 struct datahead *
451 __nscd_cache_search (request_type type, const char *key, size_t keylen,
452 const struct mapped_database *mapped, size_t datalen)
454 unsigned long int hash = __nis_hash (key, keylen) % mapped->head->module;
455 size_t datasize = mapped->datasize;
457 ref_t trail = mapped->head->array[hash];
458 trail = atomic_forced_read (trail);
459 ref_t work = trail;
460 size_t loop_cnt = datasize / (MINIMUM_HASHENTRY_SIZE
461 + offsetof (struct datahead, data) / 2);
462 int tick = 0;
464 while (work != ENDREF && work + MINIMUM_HASHENTRY_SIZE <= datasize)
466 struct hashentry *here = (struct hashentry *) (mapped->data + work);
467 ref_t here_key, here_packet;
469 #if !_STRING_ARCH_unaligned
470 /* Although during garbage collection when moving struct hashentry
471 records around we first copy from old to new location and then
472 adjust pointer from previous hashentry to it, there is no barrier
473 between those memory writes. It is very unlikely to hit it,
474 so check alignment only if a misaligned load can crash the
475 application. */
476 if ((uintptr_t) here & (__alignof__ (*here) - 1))
477 return NULL;
478 #endif
480 if (type == here->type
481 && keylen == here->len
482 && (here_key = atomic_forced_read (here->key)) + keylen <= datasize
483 && memcmp (key, mapped->data + here_key, keylen) == 0
484 && ((here_packet = atomic_forced_read (here->packet))
485 + sizeof (struct datahead) <= datasize))
487 /* We found the entry. Increment the appropriate counter. */
488 struct datahead *dh
489 = (struct datahead *) (mapped->data + here_packet);
491 #if !_STRING_ARCH_unaligned
492 if ((uintptr_t) dh & (__alignof__ (*dh) - 1))
493 return NULL;
494 #endif
496 /* See whether we must ignore the entry or whether something
497 is wrong because garbage collection is in progress. */
498 if (dh->usable
499 && here_packet + dh->allocsize <= datasize
500 && (here_packet + offsetof (struct datahead, data) + datalen
501 <= datasize))
502 return dh;
505 work = atomic_forced_read (here->next);
506 /* Prevent endless loops. This should never happen but perhaps
507 the database got corrupted, accidentally or deliberately. */
508 if (work == trail || loop_cnt-- == 0)
509 break;
510 if (tick)
512 struct hashentry *trailelem;
513 trailelem = (struct hashentry *) (mapped->data + trail);
515 #if !_STRING_ARCH_unaligned
516 /* We have to redo the checks. Maybe the data changed. */
517 if ((uintptr_t) trailelem & (__alignof__ (*trailelem) - 1))
518 return NULL;
519 #endif
521 if (trail + MINIMUM_HASHENTRY_SIZE > datasize)
522 return NULL;
524 trail = atomic_forced_read (trailelem->next);
526 tick = 1 - tick;
529 return NULL;
533 /* Create a socket connected to a name. */
535 __nscd_open_socket (const char *key, size_t keylen, request_type type,
536 void *response, size_t responselen)
538 /* This should never happen and it is something the nscd daemon
539 enforces, too. He it helps to limit the amount of stack
540 used. */
541 if (keylen > MAXKEYLEN)
542 return -1;
544 int saved_errno = errno;
546 int sock = open_socket (type, key, keylen);
547 if (sock >= 0)
549 /* Wait for data. */
550 if (wait_on_socket (sock, 5 * 1000) > 0)
552 ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response,
553 responselen));
554 if (nbytes == (ssize_t) responselen)
555 return sock;
558 __close_nocancel_nostatus (sock);
561 __set_errno (saved_errno);
563 return -1;