1 /* Copyright (C) 1998-2024 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
29 #include <sys/param.h>
31 #include <sys/socket.h>
36 #include <not-cancel.h>
37 #include <kernel-features.h>
39 #include <struct___timespec64.h>
41 #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
51 wait_on_socket (int sock
, long int usectmo
)
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 __timespec64 now
;
63 __clock_gettime64 (CLOCK_REALTIME
, &now
);
64 int64_t end
= (now
.tv_sec
* 1000 + usectmo
65 + (now
.tv_nsec
+ 500000) / 1000000);
66 long int timeout
= usectmo
;
69 n
= __poll (fds
, 1, timeout
);
70 if (n
!= -1 || errno
!= EINTR
)
73 /* Recompute the timeout time. */
74 __clock_gettime64 (CLOCK_REALTIME
, &now
);
75 timeout
= end
- ((now
.tv_sec
* 1000
76 + (now
.tv_nsec
+ 500000) / 1000000));
85 __readall (int fd
, void *buf
, size_t len
)
92 ret
= TEMP_FAILURE_RETRY (__read (fd
, buf
, n
));
95 if (__builtin_expect (ret
< 0 && errno
== EAGAIN
, 0)
96 /* The socket is still receiving data. Wait a bit more. */
97 && wait_on_socket (fd
, EXTRA_RECEIVE_TIME
) > 0)
102 buf
= (char *) buf
+ ret
;
106 return ret
< 0 ? ret
: len
- n
;
111 __readvall (int fd
, const struct iovec
*iov
, int iovcnt
)
113 ssize_t ret
= TEMP_FAILURE_RETRY (__readv (fd
, iov
, iovcnt
));
116 if (__glibc_likely (ret
== 0 || errno
!= EAGAIN
))
117 /* A genuine error or no data to read. */
120 /* The data has not all yet been received. Do as if we have not
121 read anything yet. */
126 for (int i
= 0; i
< iovcnt
; ++i
)
127 total
+= iov
[i
].iov_len
;
131 struct iovec iov_buf
[iovcnt
];
134 struct iovec
*iovp
= memcpy (iov_buf
, iov
, iovcnt
* sizeof (*iov
));
137 while (iovp
->iov_len
<= r
)
143 iovp
->iov_base
= (char *) iovp
->iov_base
+ r
;
146 r
= TEMP_FAILURE_RETRY (__readv (fd
, iovp
, iovcnt
));
149 if (__builtin_expect (r
< 0 && errno
== EAGAIN
, 0)
150 /* The socket is still receiving data. Wait a bit more. */
151 && wait_on_socket (fd
, EXTRA_RECEIVE_TIME
) > 0)
167 open_socket (request_type type
, const char *key
, size_t keylen
)
171 sock
= __socket (PF_UNIX
, SOCK_STREAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0);
175 size_t real_sizeof_reqdata
= sizeof (request_header
) + keylen
;
180 } *reqdata
= alloca (real_sizeof_reqdata
);
182 struct sockaddr_un sun
;
183 sun
.sun_family
= AF_UNIX
;
184 strcpy (sun
.sun_path
, _PATH_NSCDSOCKET
);
185 if (__connect (sock
, (struct sockaddr
*) &sun
, sizeof (sun
)) < 0
186 && errno
!= EINPROGRESS
)
189 reqdata
->req
.version
= NSCD_VERSION
;
190 reqdata
->req
.type
= type
;
191 reqdata
->req
.key_len
= keylen
;
193 memcpy (reqdata
->key
, key
, keylen
);
195 bool first_try
= true;
196 struct __timespec64 tvend
= { 0, 0 };
200 # define MSG_NOSIGNAL 0
202 ssize_t wres
= TEMP_FAILURE_RETRY (__send (sock
, reqdata
,
205 if (__glibc_likely (wres
== (ssize_t
) real_sizeof_reqdata
))
206 /* We managed to send the request. */
209 if (wres
!= -1 || errno
!= EAGAIN
)
210 /* Something is really wrong, no chance to continue. */
213 /* The daemon is busy wait for it. */
215 struct __timespec64 now
;
216 __clock_gettime64 (CLOCK_REALTIME
, &now
);
219 tvend
.tv_nsec
= now
.tv_nsec
;
220 tvend
.tv_sec
= now
.tv_sec
+ 5;
225 to
= ((tvend
.tv_sec
- now
.tv_sec
) * 1000
226 + (tvend
.tv_nsec
- now
.tv_nsec
) / 1000000);
228 struct pollfd fds
[1];
230 fds
[0].events
= POLLOUT
| POLLERR
| POLLHUP
;
231 if (__poll (fds
, 1, to
) <= 0)
232 /* The connection timed out or broke down. */
235 /* We try to write again. */
239 __close_nocancel_nostatus (sock
);
246 __nscd_unmap (struct mapped_database
*mapped
)
248 assert (mapped
->counter
== 0);
249 __munmap ((void *) mapped
->head
, mapped
->mapsize
);
254 /* Try to get a file descriptor for the shared memory 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
;
262 const size_t keylen
= strlen (key
) + 1;
263 int saved_errno
= errno
;
266 char resdata
[keylen
];
268 /* Open a socket and send the request. */
269 int sock
= open_socket (type
, key
, keylen
);
273 /* Room for the data sent along with the file descriptor. We expect
274 the key name back. */
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
);
285 char bytes
[CMSG_SPACE (sizeof (int))];
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)
305 # ifndef MSG_CMSG_CLOEXEC
306 # define MSG_CMSG_CLOEXEC 0
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))
315 int *ip
= (void *) CMSG_DATA (cmsg
);
318 if (__glibc_unlikely (n
!= keylen
&& n
!= keylen
+ sizeof (mapsize
)))
321 if (__glibc_unlikely (strcmp (resdata
, key
) != 0))
324 if (__glibc_unlikely (n
== keylen
))
326 struct __stat64_t64 st
;
327 if (__glibc_unlikely (__fstat64_time64 (mapfd
, &st
) != 0)
328 || __builtin_expect (st
.st_size
< sizeof (struct database_pers_head
),
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
349 || __builtin_expect (! head
->nscd_certainly_running
350 && (head
->timestamp
+ MAPPING_TIMEOUT
354 __munmap (mapping
, mapsize
);
358 size_t size
= (sizeof (*head
) + roundup (head
->module
* sizeof (ref_t
),
362 if (__glibc_unlikely (mapsize
< size
))
365 /* Allocate a record for the mapping. */
366 struct mapped_database
*newp
= malloc (sizeof (*newp
));
368 /* Ugh, after all we went through the memory allocation failed. */
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. */
387 __set_errno (saved_errno
);
388 #endif /* SCM_RIGHTS */
390 struct mapped_database
*oldval
= *mappedp
;
393 if (oldval
!= NULL
&& atomic_fetch_add_relaxed (&oldval
->counter
, -1) == 1)
394 __nscd_unmap (oldval
);
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
)
407 if (!__nscd_acquire_maplock (mapptr
))
410 cur
= mapptr
->mapped
;
412 if (__glibc_likely (cur
!= NO_MAPPING
))
414 /* If not mapped or timestamp not updated, request new map. */
416 || (cur
->head
->nscd_certainly_running
== 0
417 && cur
->head
->timestamp
+ MAPPING_TIMEOUT
< time_now ())
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,
428 atomic_fetch_add_relaxed (&cur
->counter
, 1);
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))
446 /* Don't return const struct datahead *, as even though the record
447 is normally constant, it can change arbitrarily during nscd
448 garbage collection. */
450 __nscd_cache_search (request_type type
, const char *key
, size_t keylen
,
451 const struct mapped_database
*mapped
, size_t datalen
)
453 unsigned long int hash
= __nss_hash (key
, keylen
) % mapped
->head
->module
;
454 size_t datasize
= mapped
->datasize
;
456 ref_t trail
= mapped
->head
->array
[hash
];
457 trail
= atomic_forced_read (trail
);
459 size_t loop_cnt
= datasize
/ (MINIMUM_HASHENTRY_SIZE
460 + offsetof (struct datahead
, data
) / 2);
463 while (work
!= ENDREF
&& work
+ MINIMUM_HASHENTRY_SIZE
<= datasize
)
465 struct hashentry
*here
= (struct hashentry
*) (mapped
->data
+ work
);
466 ref_t here_key
, here_packet
;
468 /* Although during garbage collection when moving struct hashentry
469 records around we first copy from old to new location and then
470 adjust pointer from previous hashentry to it, there is no barrier
471 between those memory writes. It is very unlikely to hit it,
472 so check alignment only if a misaligned load can crash the
474 if ((uintptr_t) here
& (__alignof__ (*here
) - 1))
477 if (type
== here
->type
478 && keylen
== here
->len
479 && (here_key
= atomic_forced_read (here
->key
)) + keylen
<= datasize
480 && memcmp (key
, mapped
->data
+ here_key
, keylen
) == 0
481 && ((here_packet
= atomic_forced_read (here
->packet
))
482 + sizeof (struct datahead
) <= datasize
))
484 /* We found the entry. Increment the appropriate counter. */
486 = (struct datahead
*) (mapped
->data
+ here_packet
);
488 if ((uintptr_t) dh
& (__alignof__ (*dh
) - 1))
491 /* See whether we must ignore the entry or whether something
492 is wrong because garbage collection is in progress. */
494 && here_packet
+ dh
->allocsize
<= datasize
495 && (here_packet
+ offsetof (struct datahead
, data
) + datalen
500 work
= atomic_forced_read (here
->next
);
501 /* Prevent endless loops. This should never happen but perhaps
502 the database got corrupted, accidentally or deliberately. */
503 if (work
== trail
|| loop_cnt
-- == 0)
507 struct hashentry
*trailelem
;
508 trailelem
= (struct hashentry
*) (mapped
->data
+ trail
);
510 /* We have to redo the checks. Maybe the data changed. */
511 if ((uintptr_t) trailelem
& (__alignof__ (*trailelem
) - 1))
514 if (trail
+ MINIMUM_HASHENTRY_SIZE
> datasize
)
517 trail
= atomic_forced_read (trailelem
->next
);
526 /* Create a socket connected to a name. */
528 __nscd_open_socket (const char *key
, size_t keylen
, request_type type
,
529 void *response
, size_t responselen
)
531 /* This should never happen and it is something the nscd daemon
532 enforces, too. He it helps to limit the amount of stack
534 if (keylen
> MAXKEYLEN
)
537 int saved_errno
= errno
;
539 int sock
= open_socket (type
, key
, keylen
);
543 if (wait_on_socket (sock
, 5 * 1000) > 0)
545 ssize_t nbytes
= TEMP_FAILURE_RETRY (__read (sock
, response
,
547 if (nbytes
== (ssize_t
) responselen
)
551 __close_nocancel_nostatus (sock
);
554 __set_errno (saved_errno
);