]> git.ipfire.org Git - thirdparty/glibc.git/blame - nscd/nscd_helper.c
Add new macro IN_MODULE to identify module in which source is built
[thirdparty/glibc.git] / nscd / nscd_helper.c
CommitLineData
d4697bc9 1/* Copyright (C) 1998-2014 Free Software Foundation, Inc.
c207f23b
UD
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
4
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.
9
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.
14
15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
c207f23b
UD
18
19#include <assert.h>
20#include <errno.h>
21#include <fcntl.h>
22#include <stdbool.h>
cfe1fc10 23#include <stddef.h>
c6dfed24 24#include <stdlib.h>
1a77d37f 25#include <string.h>
0b890d59 26#include <time.h>
c207f23b 27#include <unistd.h>
e054f494 28#include <stdint.h>
c207f23b
UD
29#include <sys/mman.h>
30#include <sys/poll.h>
31#include <sys/socket.h>
32#include <sys/stat.h>
7529e67e 33#include <sys/time.h>
c207f23b
UD
34#include <sys/uio.h>
35#include <sys/un.h>
36#include <not-cancel.h>
37#include <nis/rpcsvc/nis.h>
c418b1ba 38#include <kernel-features.h>
c207f23b
UD
39
40#include "nscd-client.h"
41
42
f7140274 43/* Extra time we wait if the socket is still receiving data. This
cfca0aa3 44 value is in milliseconds. Note that the other side is nscd on the
f7140274
UD
45 local machine and it is already transmitting data. So the wait
46 time need not be long. */
47#define EXTRA_RECEIVE_TIME 200
48
49
50static int
51wait_on_socket (int sock, long int usectmo)
52{
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))
58 {
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)
67 {
68 n = __poll (fds, 1, timeout);
69 if (n != -1 || errno != EINTR)
70 break;
71
72 /* Recompute the timeout time. */
73 (void) __gettimeofday (&now, NULL);
74 timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000);
75 }
76 }
77
78 return n;
79}
80
81
d2dc7d84
UD
82ssize_t
83__readall (int fd, void *buf, size_t len)
84{
85 size_t n = len;
86 ssize_t ret;
87 do
88 {
f7140274 89 again:
d2dc7d84
UD
90 ret = TEMP_FAILURE_RETRY (__read (fd, buf, n));
91 if (ret <= 0)
f7140274
UD
92 {
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;
97
98 break;
99 }
d2dc7d84
UD
100 buf = (char *) buf + ret;
101 n -= ret;
102 }
103 while (n > 0);
104 return ret < 0 ? ret : len - n;
105}
106
107
108ssize_t
109__readvall (int fd, const struct iovec *iov, int iovcnt)
110{
111 ssize_t ret = TEMP_FAILURE_RETRY (__readv (fd, iov, iovcnt));
112 if (ret <= 0)
f7140274 113 {
a1ffb40e 114 if (__glibc_likely (ret == 0 || errno != EAGAIN))
f7140274
UD
115 /* A genuine error or no data to read. */
116 return ret;
117
118 /* The data has not all yet been received. Do as if we have not
119 read anything yet. */
120 ret = 0;
121 }
d2dc7d84
UD
122
123 size_t total = 0;
124 for (int i = 0; i < iovcnt; ++i)
125 total += iov[i].iov_len;
126
127 if (ret < total)
128 {
129 struct iovec iov_buf[iovcnt];
130 ssize_t r = ret;
131
132 struct iovec *iovp = memcpy (iov_buf, iov, iovcnt * sizeof (*iov));
133 do
134 {
135 while (iovp->iov_len <= r)
136 {
137 r -= iovp->iov_len;
138 --iovcnt;
139 ++iovp;
140 }
141 iovp->iov_base = (char *) iovp->iov_base + r;
142 iovp->iov_len -= r;
f7140274 143 again:
d2dc7d84
UD
144 r = TEMP_FAILURE_RETRY (__readv (fd, iovp, iovcnt));
145 if (r <= 0)
f7140274
UD
146 {
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;
151
152 break;
153 }
d2dc7d84
UD
154 ret += r;
155 }
156 while (ret < total);
157 if (r < 0)
158 ret = r;
159 }
160 return ret;
161}
162
163
c207f23b 164static int
58a2d52e 165open_socket (request_type type, const char *key, size_t keylen)
c207f23b 166{
c418b1ba
UD
167 int sock;
168
169#ifdef SOCK_CLOEXEC
170# ifndef __ASSUME_SOCK_CLOEXEC
171 if (__have_sock_cloexec >= 0)
172# endif
173 {
174 sock = __socket (PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
175# ifndef __ASSUME_SOCK_CLOEXEC
176 if (__have_sock_cloexec == 0)
177 __have_sock_cloexec = sock != -1 || errno != EINVAL ? 1 : -1;
178# endif
179 }
180#endif
181#ifndef __ASSUME_SOCK_CLOEXEC
182# ifdef SOCK_CLOEXEC
183 if (__have_sock_cloexec < 0)
184# endif
185 sock = __socket (PF_UNIX, SOCK_STREAM, 0);
186#endif
c207f23b
UD
187 if (sock < 0)
188 return -1;
189
c6dfed24 190 size_t real_sizeof_reqdata = sizeof (request_header) + keylen;
58a2d52e
UD
191 struct
192 {
193 request_header req;
c6dfed24
RM
194 char key[];
195 } *reqdata = alloca (real_sizeof_reqdata);
58a2d52e 196
c418b1ba
UD
197#ifndef __ASSUME_SOCK_CLOEXEC
198# ifdef SOCK_NONBLOCK
199 if (__have_sock_cloexec < 0)
200# endif
201 /* Make socket non-blocking. */
202 __fcntl (sock, F_SETFL, O_RDWR | O_NONBLOCK);
203#endif
c207f23b
UD
204
205 struct sockaddr_un sun;
206 sun.sun_family = AF_UNIX;
207 strcpy (sun.sun_path, _PATH_NSCDSOCKET);
208 if (__connect (sock, (struct sockaddr *) &sun, sizeof (sun)) < 0
209 && errno != EINPROGRESS)
210 goto out;
211
c6dfed24
RM
212 reqdata->req.version = NSCD_VERSION;
213 reqdata->req.type = type;
214 reqdata->req.key_len = keylen;
58a2d52e 215
c6dfed24 216 memcpy (reqdata->key, key, keylen);
58a2d52e
UD
217
218 bool first_try = true;
219 struct timeval tvend;
f2ccf983
UD
220 /* Fake initializing tvend. */
221 asm ("" : "=m" (tvend));
58a2d52e
UD
222 while (1)
223 {
224#ifndef MSG_NOSIGNAL
225# define MSG_NOSIGNAL 0
226#endif
c6dfed24 227 ssize_t wres = TEMP_FAILURE_RETRY (__send (sock, reqdata,
6eea8e0d 228 real_sizeof_reqdata,
58a2d52e 229 MSG_NOSIGNAL));
a1ffb40e 230 if (__glibc_likely (wres == (ssize_t) real_sizeof_reqdata))
58a2d52e
UD
231 /* We managed to send the request. */
232 return sock;
233
234 if (wres != -1 || errno != EAGAIN)
235 /* Something is really wrong, no chance to continue. */
236 break;
237
238 /* The daemon is busy wait for it. */
239 int to;
f2ccf983
UD
240 struct timeval now;
241 (void) __gettimeofday (&now, NULL);
58a2d52e
UD
242 if (first_try)
243 {
f2ccf983
UD
244 tvend.tv_usec = now.tv_usec;
245 tvend.tv_sec = now.tv_sec + 5;
58a2d52e
UD
246 to = 5 * 1000;
247 first_try = false;
248 }
249 else
f2ccf983
UD
250 to = ((tvend.tv_sec - now.tv_sec) * 1000
251 + (tvend.tv_usec - now.tv_usec) / 1000);
58a2d52e
UD
252
253 struct pollfd fds[1];
254 fds[0].fd = sock;
255 fds[0].events = POLLOUT | POLLERR | POLLHUP;
256 if (__poll (fds, 1, to) <= 0)
257 /* The connection timed out or broke down. */
258 break;
259
260 /* We try to write again. */
261 }
c207f23b
UD
262
263 out:
264 close_not_cancel_no_status (sock);
265
266 return -1;
267}
268
269
270void
271__nscd_unmap (struct mapped_database *mapped)
272{
273 assert (mapped->counter == 0);
62417d7e 274 __munmap ((void *) mapped->head, mapped->mapsize);
c207f23b
UD
275 free (mapped);
276}
277
278
279/* Try to get a file descriptor for the shared meory segment
280 containing the database. */
3a2c0242
UD
281struct mapped_database *
282__nscd_get_mapping (request_type type, const char *key,
283 struct mapped_database **mappedp)
c207f23b
UD
284{
285 struct mapped_database *result = NO_MAPPING;
286#ifdef SCM_RIGHTS
287 const size_t keylen = strlen (key) + 1;
c207f23b
UD
288 int saved_errno = errno;
289
290 int mapfd = -1;
58a2d52e 291 char resdata[keylen];
c207f23b 292
58a2d52e
UD
293 /* Open a socket and send the request. */
294 int sock = open_socket (type, key, keylen);
c207f23b
UD
295 if (sock < 0)
296 goto out;
297
c207f23b
UD
298 /* Room for the data sent along with the file descriptor. We expect
299 the key name back. */
f3c54060
UD
300 uint64_t mapsize;
301 struct iovec iov[2];
c207f23b
UD
302 iov[0].iov_base = resdata;
303 iov[0].iov_len = keylen;
f3c54060
UD
304 iov[1].iov_base = &mapsize;
305 iov[1].iov_len = sizeof (mapsize);
c207f23b 306
7529e67e
UD
307 union
308 {
309 struct cmsghdr hdr;
310 char bytes[CMSG_SPACE (sizeof (int))];
311 } buf;
f3c54060 312 struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 2,
7529e67e
UD
313 .msg_control = buf.bytes,
314 .msg_controllen = sizeof (buf) };
c207f23b
UD
315 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
316
317 cmsg->cmsg_level = SOL_SOCKET;
318 cmsg->cmsg_type = SCM_RIGHTS;
319 cmsg->cmsg_len = CMSG_LEN (sizeof (int));
320
7529e67e
UD
321 /* This access is well-aligned since BUF is correctly aligned for an
322 int and CMSG_DATA preserves this alignment. */
6cc8844f 323 memset (CMSG_DATA (cmsg), '\xff', sizeof (int));
c207f23b
UD
324
325 msg.msg_controllen = cmsg->cmsg_len;
326
f7140274 327 if (wait_on_socket (sock, 5 * 1000) <= 0)
c207f23b
UD
328 goto out_close2;
329
dde0763a
UD
330# ifndef MSG_CMSG_CLOEXEC
331# define MSG_CMSG_CLOEXEC 0
332# endif
f3c54060 333 ssize_t n = TEMP_FAILURE_RETRY (__recvmsg (sock, &msg, MSG_CMSG_CLOEXEC));
aadd7d9d 334
5da4373c
UD
335 if (__builtin_expect (CMSG_FIRSTHDR (&msg) == NULL
336 || (CMSG_FIRSTHDR (&msg)->cmsg_len
337 != CMSG_LEN (sizeof (int))), 0))
338 goto out_close2;
11bf311e 339
6cc8844f
UD
340 int *ip = (void *) CMSG_DATA (cmsg);
341 mapfd = *ip;
ee5d5755 342
a1ffb40e 343 if (__glibc_unlikely (n != keylen && n != keylen + sizeof (mapsize)))
f3c54060
UD
344 goto out_close;
345
a1ffb40e 346 if (__glibc_unlikely (strcmp (resdata, key) != 0))
c207f23b
UD
347 goto out_close;
348
a1ffb40e 349 if (__glibc_unlikely (n == keylen))
f3c54060
UD
350 {
351 struct stat64 st;
352 if (__builtin_expect (fstat64 (mapfd, &st) != 0, 0)
353 || __builtin_expect (st.st_size < sizeof (struct database_pers_head),
354 0))
355 goto out_close;
356
357 mapsize = st.st_size;
358 }
359
c207f23b 360 /* The file is large enough, map it now. */
f3c54060 361 void *mapping = __mmap (NULL, mapsize, PROT_READ, MAP_SHARED, mapfd, 0);
a1ffb40e 362 if (__glibc_likely (mapping != MAP_FAILED))
c207f23b 363 {
0adfcc05
UD
364 /* Check whether the database is correct and up-to-date. */
365 struct database_pers_head *head = mapping;
366
367 if (__builtin_expect (head->version != DB_VERSION, 0)
368 || __builtin_expect (head->header_size != sizeof (*head), 0)
27c377dd
UD
369 /* Catch some misconfiguration. The server should catch
370 them now but some older versions did not. */
371 || __builtin_expect (head->module == 0, 0)
0adfcc05
UD
372 /* This really should not happen but who knows, maybe the update
373 thread got stuck. */
374 || __builtin_expect (! head->nscd_certainly_running
375 && (head->timestamp + MAPPING_TIMEOUT
376 < time (NULL)), 0))
c207f23b 377 {
0adfcc05 378 out_unmap:
f3c54060 379 __munmap (mapping, mapsize);
c207f23b
UD
380 goto out_close;
381 }
382
0adfcc05
UD
383 size_t size = (sizeof (*head) + roundup (head->module * sizeof (ref_t),
384 ALIGN)
385 + head->data_size);
386
a1ffb40e 387 if (__glibc_unlikely (mapsize < size))
0adfcc05
UD
388 goto out_unmap;
389
390 /* Allocate a record for the mapping. */
391 struct mapped_database *newp = malloc (sizeof (*newp));
392 if (newp == NULL)
393 /* Ugh, after all we went through the memory allocation failed. */
394 goto out_unmap;
395
c207f23b 396 newp->head = mapping;
0adfcc05
UD
397 newp->data = ((char *) mapping + head->header_size
398 + roundup (head->module * sizeof (ref_t), ALIGN));
c207f23b 399 newp->mapsize = size;
0adfcc05 400 newp->datasize = head->data_size;
c207f23b
UD
401 /* Set counter to 1 to show it is usable. */
402 newp->counter = 1;
403
404 result = newp;
405 }
406
407 out_close:
408 __close (mapfd);
409 out_close2:
410 __close (sock);
411 out:
412 __set_errno (saved_errno);
413#endif /* SCM_RIGHTS */
414
415 struct mapped_database *oldval = *mappedp;
416 *mappedp = result;
417
418 if (oldval != NULL && atomic_decrement_val (&oldval->counter) == 0)
419 __nscd_unmap (oldval);
420
421 return result;
422}
423
c207f23b
UD
424struct mapped_database *
425__nscd_get_map_ref (request_type type, const char *name,
388df58d 426 volatile struct locked_map_ptr *mapptr, int *gc_cyclep)
c207f23b
UD
427{
428 struct mapped_database *cur = mapptr->mapped;
429 if (cur == NO_MAPPING)
430 return cur;
431
509072a0
AJ
432 if (!__nscd_acquire_maplock (mapptr))
433 return NO_MAPPING;
c207f23b
UD
434
435 cur = mapptr->mapped;
436
a1ffb40e 437 if (__glibc_likely (cur != NO_MAPPING))
c207f23b
UD
438 {
439 /* If not mapped or timestamp not updated, request new map. */
440 if (cur == NULL
081fc592 441 || (cur->head->nscd_certainly_running == 0
0b25a49a
UD
442 && cur->head->timestamp + MAPPING_TIMEOUT < time (NULL))
443 || cur->head->data_size > cur->datasize)
3a2c0242
UD
444 cur = __nscd_get_mapping (type, name,
445 (struct mapped_database **) &mapptr->mapped);
c207f23b 446
a1ffb40e 447 if (__glibc_likely (cur != NO_MAPPING))
c207f23b
UD
448 {
449 if (__builtin_expect (((*gc_cyclep = cur->head->gc_cycle) & 1) != 0,
450 0))
451 cur = NO_MAPPING;
452 else
453 atomic_increment (&cur->counter);
454 }
455 }
456
457 mapptr->lock = 0;
458
459 return cur;
460}
461
462
5078fff6
JJ
463/* Using sizeof (hashentry) is not always correct to determine the size of
464 the data structure as found in the nscd cache. The program could be
465 a 64-bit process and nscd could be a 32-bit process. In this case
466 sizeof (hashentry) would overestimate the size. The following is
467 the minimum size of such an entry, good enough for our tests here. */
468#define MINIMUM_HASHENTRY_SIZE \
469 (offsetof (struct hashentry, dellist) + sizeof (int32_t))
470
471
1a77d37f
JJ
472/* Don't return const struct datahead *, as eventhough the record
473 is normally constant, it can change arbitrarily during nscd
474 garbage collection. */
475struct datahead *
c207f23b 476__nscd_cache_search (request_type type, const char *key, size_t keylen,
cfe1fc10 477 const struct mapped_database *mapped, size_t datalen)
c207f23b
UD
478{
479 unsigned long int hash = __nis_hash (key, keylen) % mapped->head->module;
0b25a49a 480 size_t datasize = mapped->datasize;
c207f23b 481
a6fa5328 482 ref_t trail = mapped->head->array[hash];
cfe1fc10 483 trail = atomic_forced_read (trail);
a6fa5328 484 ref_t work = trail;
5078fff6
JJ
485 size_t loop_cnt = datasize / (MINIMUM_HASHENTRY_SIZE
486 + offsetof (struct datahead, data) / 2);
a6fa5328
UD
487 int tick = 0;
488
5078fff6 489 while (work != ENDREF && work + MINIMUM_HASHENTRY_SIZE <= datasize)
c207f23b
UD
490 {
491 struct hashentry *here = (struct hashentry *) (mapped->data + work);
cfe1fc10 492 ref_t here_key, here_packet;
c207f23b 493
27822ce6 494#if !_STRING_ARCH_unaligned
1a77d37f
JJ
495 /* Although during garbage collection when moving struct hashentry
496 records around we first copy from old to new location and then
497 adjust pointer from previous hashentry to it, there is no barrier
498 between those memory writes. It is very unlikely to hit it,
499 so check alignment only if a misaligned load can crash the
500 application. */
501 if ((uintptr_t) here & (__alignof__ (*here) - 1))
502 return NULL;
503#endif
504
0b25a49a
UD
505 if (type == here->type
506 && keylen == here->len
cfe1fc10
JJ
507 && (here_key = atomic_forced_read (here->key)) + keylen <= datasize
508 && memcmp (key, mapped->data + here_key, keylen) == 0
509 && ((here_packet = atomic_forced_read (here->packet))
510 + sizeof (struct datahead) <= datasize))
c207f23b
UD
511 {
512 /* We found the entry. Increment the appropriate counter. */
1a77d37f 513 struct datahead *dh
cfe1fc10 514 = (struct datahead *) (mapped->data + here_packet);
c207f23b 515
27822ce6 516#if !_STRING_ARCH_unaligned
1a77d37f
JJ
517 if ((uintptr_t) dh & (__alignof__ (*dh) - 1))
518 return NULL;
519#endif
520
c207f23b
UD
521 /* See whether we must ignore the entry or whether something
522 is wrong because garbage collection is in progress. */
cfe1fc10
JJ
523 if (dh->usable
524 && here_packet + dh->allocsize <= datasize
525 && (here_packet + offsetof (struct datahead, data) + datalen
526 <= datasize))
c207f23b
UD
527 return dh;
528 }
529
cfe1fc10 530 work = atomic_forced_read (here->next);
8c7661bc
UD
531 /* Prevent endless loops. This should never happen but perhaps
532 the database got corrupted, accidentally or deliberately. */
95410b7b 533 if (work == trail || loop_cnt-- == 0)
8c7661bc 534 break;
a6fa5328
UD
535 if (tick)
536 {
537 struct hashentry *trailelem;
538 trailelem = (struct hashentry *) (mapped->data + trail);
539
27822ce6 540#if !_STRING_ARCH_unaligned
a6fa5328
UD
541 /* We have to redo the checks. Maybe the data changed. */
542 if ((uintptr_t) trailelem & (__alignof__ (*trailelem) - 1))
543 return NULL;
544#endif
cfe1fc10 545
5078fff6 546 if (trail + MINIMUM_HASHENTRY_SIZE > datasize)
cfe1fc10
JJ
547 return NULL;
548
549 trail = atomic_forced_read (trailelem->next);
a6fa5328
UD
550 }
551 tick = 1 - tick;
c207f23b
UD
552 }
553
554 return NULL;
555}
556
557
558/* Create a socket connected to a name. */
559int
560__nscd_open_socket (const char *key, size_t keylen, request_type type,
561 void *response, size_t responselen)
562{
58a2d52e
UD
563 /* This should never happen and it is something the nscd daemon
564 enforces, too. He it helps to limit the amount of stack
565 used. */
566 if (keylen > MAXKEYLEN)
567 return -1;
568
c207f23b
UD
569 int saved_errno = errno;
570
58a2d52e 571 int sock = open_socket (type, key, keylen);
c207f23b
UD
572 if (sock >= 0)
573 {
58a2d52e 574 /* Wait for data. */
f7140274 575 if (wait_on_socket (sock, 5 * 1000) > 0)
7529e67e 576 {
58a2d52e
UD
577 ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response,
578 responselen));
7529e67e
UD
579 if (nbytes == (ssize_t) responselen)
580 return sock;
c207f23b
UD
581 }
582
583 close_not_cancel_no_status (sock);
584 }
585
586 __set_errno (saved_errno);
587
588 return -1;
589}