SHA256
3
0
forked from pool/glibc
glibc/nss-separate-state-getXXent.patch
Andreas Schwab d6f647d047 Accepting request 293890 from home:Andreas_Schwab:Factory
- powerpc-software-sqrt.patch: Fix powerpc software sqrt (BZ #17964, BZ
  #17967)
- nss-separate-state-getXXent.patch: Separate internal state between
  getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
- static-tls-dtv-limit.patch: Fix DTV race, assert, DTV_SURPLUS Static TLS
  limit, and nptl_db garbage (bsc#919678, BZ #17090, BZ #17620, BZ #17621,
  BZ #17628)

OBS-URL: https://build.opensuse.org/request/show/293890
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=398
2015-04-01 09:51:42 +00:00

716 lines
20 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[BZ #18007]
* nis/nss_compat/compat-grp.c (internal_endgrent): Add parameter
needent, call nss_endgrent only if non-zero.
(_nss_compat_endgrent): Pass non-zero.
(_nss_compat_getgrnam_r, _nss_compat_getgrgid_r): Pass zero.
* nis/nss_compat/compat-pwd.c (internal_endpwent): Add parameter
needent, call nss_endpwent only if non-zero.
(_nss_compat_endpwent): Pass non-zero.
(_nss_compat_getpwnam_r, _nss_compat_getpwuid_r): Pass zero.
* nis/nss_compat/compat-spwd.c (internal_setspent): Add parameter
needent, call nss_setspent only if non-zero.
(_nss_compat_setspent): Pass non-zero.
(internal_endspent): Add parameter needent, call nss_endspent only
if non-zero.
(_nss_compat_endspent, _nss_compat_getspent_r): Pass non-zero.
(_nss_compat_getspnam_r): Pass zero.
* nss/nss_files/files-XXX.c (position, last_use, keep_stream):
Remove. All uses removed.
(internal_setent): Remove parameter stayopen, add parameter
stream. Use it instead of global variable.
(CONCAT(_nss_files_set,ENTNAME)): Pass global stream.
(internal_endent, internal_getent): Add parameter stream. Use it
instead of global variable.
(CONCAT(_nss_files_end,ENTNAME))
(CONCAT(_nss_files_get,ENTNAME_r)): Pass global stream.
(_nss_files_get##name##_r): Pass local stream. Remove locking.
* nss/nss_files/files-alias.c (position, last_use): Remove. All
uses removed.
(internal_setent, internal_endent): Add parameter stream. Use it
instead of global variable.
(_nss_files_setaliasent, _nss_files_endaliasent): Pass global
stream.
(get_next_alias): Add parameter stream.
(_nss_files_getaliasent_r): Pass global stream.
(_nss_files_getaliasbyname_r): Pass local stream. Remove locking.
* nss/nss_files/files-hosts.c (_nss_files_gethostbyname3_r)
(_nss_files_gethostbyname4_r): Pass local stream to
internal_setent, internal_getent and internal_endent. Remove
locking.
Index: glibc-2.21/nis/nss_compat/compat-grp.c
===================================================================
--- glibc-2.21.orig/nis/nss_compat/compat-grp.c
+++ glibc-2.21/nis/nss_compat/compat-grp.c
@@ -192,9 +192,9 @@ _nss_compat_setgrent (int stayopen)
static enum nss_status
-internal_endgrent (ent_t *ent)
+internal_endgrent (ent_t *ent, int needent)
{
- if (nss_endgrent)
+ if (needent && nss_endgrent)
nss_endgrent ();
if (ent->stream != NULL)
@@ -222,7 +222,7 @@ _nss_compat_endgrent (void)
__libc_lock_lock (lock);
- result = internal_endgrent (&ext_ent);
+ result = internal_endgrent (&ext_ent, 1);
__libc_lock_unlock (lock);
@@ -532,7 +532,7 @@ _nss_compat_getgrnam_r (const char *name
if (result == NSS_STATUS_SUCCESS)
result = internal_getgrnam_r (name, grp, &ent, buffer, buflen, errnop);
- internal_endgrent (&ent);
+ internal_endgrent (&ent, 0);
return result;
}
@@ -661,7 +661,7 @@ _nss_compat_getgrgid_r (gid_t gid, struc
if (result == NSS_STATUS_SUCCESS)
result = internal_getgrgid_r (gid, grp, &ent, buffer, buflen, errnop);
- internal_endgrent (&ent);
+ internal_endgrent (&ent, 0);
return result;
}
Index: glibc-2.21/nis/nss_compat/compat-pwd.c
===================================================================
--- glibc-2.21.orig/nis/nss_compat/compat-pwd.c
+++ glibc-2.21/nis/nss_compat/compat-pwd.c
@@ -309,9 +309,9 @@ _nss_compat_setpwent (int stayopen)
static enum nss_status
-internal_endpwent (ent_t *ent)
+internal_endpwent (ent_t *ent, int needent)
{
- if (nss_endpwent)
+ if (needent && nss_endpwent)
nss_endpwent ();
if (ent->stream != NULL)
@@ -346,7 +346,7 @@ _nss_compat_endpwent (void)
__libc_lock_lock (lock);
- result = internal_endpwent (&ext_ent);
+ result = internal_endpwent (&ext_ent, 1);
__libc_lock_unlock (lock);
@@ -871,7 +871,7 @@ _nss_compat_getpwnam_r (const char *name
if (result == NSS_STATUS_SUCCESS)
result = internal_getpwnam_r (name, pwd, &ent, buffer, buflen, errnop);
- internal_endpwent (&ent);
+ internal_endpwent (&ent, 0);
return result;
}
@@ -1110,7 +1110,7 @@ _nss_compat_getpwuid_r (uid_t uid, struc
if (result == NSS_STATUS_SUCCESS)
result = internal_getpwuid_r (uid, pwd, &ent, buffer, buflen, errnop);
- internal_endpwent (&ent);
+ internal_endpwent (&ent, 0);
return result;
}
Index: glibc-2.21/nis/nss_compat/compat-spwd.c
===================================================================
--- glibc-2.21.orig/nis/nss_compat/compat-spwd.c
+++ glibc-2.21/nis/nss_compat/compat-spwd.c
@@ -169,7 +169,7 @@ copy_spwd_changes (struct spwd *dest, st
}
static enum nss_status
-internal_setspent (ent_t *ent, int stayopen)
+internal_setspent (ent_t *ent, int stayopen, int needent)
{
enum nss_status status = NSS_STATUS_SUCCESS;
@@ -239,7 +239,7 @@ internal_setspent (ent_t *ent, int stayo
give_spwd_free (&ent->pwd);
- if (status == NSS_STATUS_SUCCESS && nss_setspent)
+ if (needent && status == NSS_STATUS_SUCCESS && nss_setspent)
ent->setent_status = nss_setspent (stayopen);
return status;
@@ -256,7 +256,7 @@ _nss_compat_setspent (int stayopen)
if (ni == NULL)
init_nss_interface ();
- result = internal_setspent (&ext_ent, stayopen);
+ result = internal_setspent (&ext_ent, stayopen, 1);
__libc_lock_unlock (lock);
@@ -265,9 +265,9 @@ _nss_compat_setspent (int stayopen)
static enum nss_status
-internal_endspent (ent_t *ent)
+internal_endspent (ent_t *ent, int needent)
{
- if (nss_endspent)
+ if (needent && nss_endspent)
nss_endspent ();
if (ent->stream != NULL)
@@ -303,7 +303,7 @@ _nss_compat_endspent (void)
__libc_lock_lock (lock);
- result = internal_endspent (&ext_ent);
+ result = internal_endspent (&ext_ent, 1);
__libc_lock_unlock (lock);
@@ -658,7 +658,7 @@ _nss_compat_getspent_r (struct spwd *pwd
init_nss_interface ();
if (ext_ent.stream == NULL)
- result = internal_setspent (&ext_ent, 1);
+ result = internal_setspent (&ext_ent, 1, 1);
if (result == NSS_STATUS_SUCCESS)
result = internal_getspent_r (pwd, &ext_ent, buffer, buflen, errnop);
@@ -830,12 +830,12 @@ _nss_compat_getspnam_r (const char *name
__libc_lock_unlock (lock);
- result = internal_setspent (&ent, 0);
+ result = internal_setspent (&ent, 0, 0);
if (result == NSS_STATUS_SUCCESS)
result = internal_getspnam_r (name, pwd, &ent, buffer, buflen, errnop);
- internal_endspent (&ent);
+ internal_endspent (&ent, 0);
return result;
}
Index: glibc-2.21/nss/nss_files/files-XXX.c
===================================================================
--- glibc-2.21.orig/nss/nss_files/files-XXX.c
+++ glibc-2.21/nss/nss_files/files-XXX.c
@@ -63,21 +63,18 @@ __libc_lock_define_initialized (static,
/* Maintenance of the shared stream open on the database file. */
static FILE *stream;
-static fpos_t position;
-static enum { nouse, getent, getby } last_use;
-static int keep_stream;
/* Open database file if not already opened. */
static enum nss_status
-internal_setent (int stayopen)
+internal_setent (FILE **stream)
{
enum nss_status status = NSS_STATUS_SUCCESS;
- if (stream == NULL)
+ if (*stream == NULL)
{
- stream = fopen (DATAFILE, "rce");
+ *stream = fopen (DATAFILE, "rce");
- if (stream == NULL)
+ if (*stream == NULL)
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
else
{
@@ -90,7 +87,7 @@ internal_setent (int stayopen)
int result;
int flags;
- result = flags = fcntl (fileno (stream), F_GETFD, 0);
+ result = flags = fcntl (fileno (*stream), F_GETFD, 0);
if (result >= 0)
{
# ifdef O_CLOEXEC
@@ -100,15 +97,15 @@ internal_setent (int stayopen)
# endif
{
flags |= FD_CLOEXEC;
- result = fcntl (fileno (stream), F_SETFD, flags);
+ result = fcntl (fileno (*stream), F_SETFD, flags);
}
}
if (result < 0)
{
/* Something went wrong. Close the stream and return a
failure. */
- fclose (stream);
- stream = NULL;
+ fclose (*stream);
+ *stream = NULL;
status = NSS_STATUS_UNAVAIL;
}
}
@@ -116,11 +113,7 @@ internal_setent (int stayopen)
}
}
else
- rewind (stream);
-
- /* Remember STAYOPEN flag. */
- if (stream != NULL)
- keep_stream |= stayopen;
+ rewind (*stream);
return status;
}
@@ -134,16 +127,7 @@ CONCAT(_nss_files_set,ENTNAME) (int stay
__libc_lock_lock (lock);
- status = internal_setent (stayopen);
-
- if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
- {
- fclose (stream);
- stream = NULL;
- status = NSS_STATUS_UNAVAIL;
- }
-
- last_use = getent;
+ status = internal_setent (&stream);
__libc_lock_unlock (lock);
@@ -153,12 +137,12 @@ CONCAT(_nss_files_set,ENTNAME) (int stay
/* Close the database file. */
static void
-internal_endent (void)
+internal_endent (FILE **stream)
{
- if (stream != NULL)
+ if (*stream != NULL)
{
- fclose (stream);
- stream = NULL;
+ fclose (*stream);
+ *stream = NULL;
}
}
@@ -169,10 +153,7 @@ CONCAT(_nss_files_end,ENTNAME) (void)
{
__libc_lock_lock (lock);
- internal_endent ();
-
- /* Reset STAYOPEN flag. */
- keep_stream = 0;
+ internal_endent (&stream);
__libc_lock_unlock (lock);
@@ -227,7 +208,7 @@ get_contents (char *linebuf, size_t len,
/* Parsing the database file into `struct STRUCTURE' data structures. */
static enum nss_status
-internal_getent (struct STRUCTURE *result,
+internal_getent (FILE *stream, struct STRUCTURE *result,
char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO
EXTRA_ARGS_DECL)
{
@@ -300,45 +281,14 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct
{
int save_errno = errno;
- status = internal_setent (0);
+ status = internal_setent (&stream);
__set_errno (save_errno);
-
- if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
- {
- fclose (stream);
- stream = NULL;
- status = NSS_STATUS_UNAVAIL;
- }
}
if (status == NSS_STATUS_SUCCESS)
- {
- /* If the last use was not by the getent function we need the
- position the stream. */
- if (last_use != getent)
- {
- if (fsetpos (stream, &position) < 0)
- status = NSS_STATUS_UNAVAIL;
- else
- last_use = getent;
- }
-
- if (status == NSS_STATUS_SUCCESS)
- {
- status = internal_getent (result, buffer, buflen, errnop
- H_ERRNO_ARG EXTRA_ARGS_VALUE);
-
- /* Remember this position if we were successful. If the
- operation failed we give the user a chance to repeat the
- operation (perhaps the buffer was too small). */
- if (status == NSS_STATUS_SUCCESS)
- fgetpos (stream, &position);
- else
- /* We must make sure we reposition the stream the next call. */
- last_use = nouse;
- }
- }
+ status = internal_getent (stream, result, buffer, buflen, errnop
+ H_ERRNO_ARG EXTRA_ARGS_VALUE);
__libc_lock_unlock (lock);
@@ -364,27 +314,20 @@ _nss_files_get##name##_r (proto,
size_t buflen, int *errnop H_ERRNO_PROTO) \
{ \
enum nss_status status; \
+ FILE *stream = NULL; \
\
- __libc_lock_lock (lock); \
- \
- /* Reset file pointer to beginning or open file. */ \
- status = internal_setent (keep_stream); \
+ /* Open file. */ \
+ status = internal_setent (&stream); \
\
if (status == NSS_STATUS_SUCCESS) \
{ \
- /* Tell getent function that we have repositioned the file pointer. */ \
- last_use = getby; \
- \
- while ((status = internal_getent (result, buffer, buflen, errnop \
+ while ((status = internal_getent (stream, result, buffer, buflen, errnop \
H_ERRNO_ARG EXTRA_ARGS_VALUE)) \
== NSS_STATUS_SUCCESS) \
{ break_if_match } \
\
- if (! keep_stream) \
- internal_endent (); \
+ internal_endent (&stream); \
} \
\
- __libc_lock_unlock (lock); \
- \
return status; \
}
Index: glibc-2.21/nss/nss_files/files-alias.c
===================================================================
--- glibc-2.21.orig/nss/nss_files/files-alias.c
+++ glibc-2.21/nss/nss_files/files-alias.c
@@ -36,20 +36,18 @@ __libc_lock_define_initialized (static,
/* Maintenance of the shared stream open on the database file. */
static FILE *stream;
-static fpos_t position;
-static enum { nouse, getent, getby } last_use;
static enum nss_status
-internal_setent (void)
+internal_setent (FILE **stream)
{
enum nss_status status = NSS_STATUS_SUCCESS;
- if (stream == NULL)
+ if (*stream == NULL)
{
- stream = fopen ("/etc/aliases", "rce");
+ *stream = fopen ("/etc/aliases", "rce");
- if (stream == NULL)
+ if (*stream == NULL)
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
else
{
@@ -62,7 +60,7 @@ internal_setent (void)
int result;
int flags;
- result = flags = fcntl (fileno (stream), F_GETFD, 0);
+ result = flags = fcntl (fileno (*stream), F_GETFD, 0);
if (result >= 0)
{
# ifdef O_CLOEXEC
@@ -72,14 +70,14 @@ internal_setent (void)
# endif
{
flags |= FD_CLOEXEC;
- result = fcntl (fileno (stream), F_SETFD, flags);
+ result = fcntl (fileno (*stream), F_SETFD, flags);
}
}
if (result < 0)
{
/* Something went wrong. Close the stream and return a
failure. */
- fclose (stream);
+ fclose (*stream);
stream = NULL;
status = NSS_STATUS_UNAVAIL;
}
@@ -88,7 +86,7 @@ internal_setent (void)
}
}
else
- rewind (stream);
+ rewind (*stream);
return status;
}
@@ -102,16 +100,7 @@ _nss_files_setaliasent (void)
__libc_lock_lock (lock);
- status = internal_setent ();
-
- if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
- {
- fclose (stream);
- stream = NULL;
- status = NSS_STATUS_UNAVAIL;
- }
-
- last_use = getent;
+ status = internal_setent (&stream);
__libc_lock_unlock (lock);
@@ -121,12 +110,12 @@ _nss_files_setaliasent (void)
/* Close the database file. */
static void
-internal_endent (void)
+internal_endent (FILE **stream)
{
- if (stream != NULL)
+ if (*stream != NULL)
{
- fclose (stream);
- stream = NULL;
+ fclose (*stream);
+ *stream = NULL;
}
}
@@ -137,7 +126,7 @@ _nss_files_endaliasent (void)
{
__libc_lock_lock (lock);
- internal_endent ();
+ internal_endent (&stream);
__libc_lock_unlock (lock);
@@ -146,7 +135,7 @@ _nss_files_endaliasent (void)
/* Parsing the database file into `struct aliasent' data structures. */
static enum nss_status
-get_next_alias (const char *match, struct aliasent *result,
+get_next_alias (FILE *stream, const char *match, struct aliasent *result,
char *buffer, size_t buflen, int *errnop)
{
enum nss_status status = NSS_STATUS_NOTFOUND;
@@ -397,35 +386,16 @@ _nss_files_getaliasent_r (struct aliasen
/* Be prepared that the set*ent function was not called before. */
if (stream == NULL)
- status = internal_setent ();
+ status = internal_setent (&stream);
if (status == NSS_STATUS_SUCCESS)
{
- /* If the last use was not by the getent function we need the
- position the stream. */
- if (last_use != getent)
- {
- if (fsetpos (stream, &position) < 0)
- status = NSS_STATUS_UNAVAIL;
- else
- last_use = getent;
- }
-
- if (status == NSS_STATUS_SUCCESS)
- {
- result->alias_local = 1;
+ result->alias_local = 1;
- /* Read lines until we get a definite result. */
- do
- status = get_next_alias (NULL, result, buffer, buflen, errnop);
- while (status == NSS_STATUS_RETURN);
-
- /* If we successfully read an entry remember this position. */
- if (status == NSS_STATUS_SUCCESS)
- fgetpos (stream, &position);
- else
- last_use = nouse;
- }
+ /* Read lines until we get a definite result. */
+ do
+ status = get_next_alias (stream, NULL, result, buffer, buflen, errnop);
+ while (status == NSS_STATUS_RETURN);
}
__libc_lock_unlock (lock);
@@ -440,6 +410,7 @@ _nss_files_getaliasbyname_r (const char
{
/* Return next entry in host file. */
enum nss_status status = NSS_STATUS_SUCCESS;
+ FILE *stream = NULL;
if (name == NULL)
{
@@ -447,11 +418,8 @@ _nss_files_getaliasbyname_r (const char
return NSS_STATUS_UNAVAIL;
}
- __libc_lock_lock (lock);
-
- /* Open the stream or rest it. */
- status = internal_setent ();
- last_use = getby;
+ /* Open the stream. */
+ status = internal_setent (&stream);
if (status == NSS_STATUS_SUCCESS)
{
@@ -459,13 +427,11 @@ _nss_files_getaliasbyname_r (const char
/* Read lines until we get a definite result. */
do
- status = get_next_alias (name, result, buffer, buflen, errnop);
+ status = get_next_alias (stream, name, result, buffer, buflen, errnop);
while (status == NSS_STATUS_RETURN);
}
- internal_endent ();
-
- __libc_lock_unlock (lock);
+ internal_endent (&stream);
return status;
}
Index: glibc-2.21/nss/nss_files/files-hosts.c
===================================================================
--- glibc-2.21.orig/nss/nss_files/files-hosts.c
+++ glibc-2.21/nss/nss_files/files-hosts.c
@@ -115,14 +115,13 @@ _nss_files_gethostbyname3_r (const char
char *buffer, size_t buflen, int *errnop,
int *herrnop, int32_t *ttlp, char **canonp)
{
+ FILE *stream = NULL;
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data);
buffer += pad;
buflen = buflen > pad ? buflen - pad : 0;
- __libc_lock_lock (lock);
-
- /* Reset file pointer to beginning or open file. */
- enum nss_status status = internal_setent (keep_stream);
+ /* Open file. */
+ enum nss_status status = internal_setent (&stream);
if (status == NSS_STATUS_SUCCESS)
{
@@ -130,10 +129,7 @@ _nss_files_gethostbyname3_r (const char
addresses to IPv6 addresses really the right thing to do? */
int flags = ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0);
- /* Tell getent function that we have repositioned the file pointer. */
- last_use = getby;
-
- while ((status = internal_getent (result, buffer, buflen, errnop,
+ while ((status = internal_getent (stream, result, buffer, buflen, errnop,
herrnop, af, flags))
== NSS_STATUS_SUCCESS)
{
@@ -160,7 +156,7 @@ _nss_files_gethostbyname3_r (const char
bufferend = (char *) &result->h_aliases[naliases + 1];
again:
- while ((status = internal_getent (&tmp_result_buf, tmp_buffer,
+ while ((status = internal_getent (stream, &tmp_result_buf, tmp_buffer,
tmp_buflen, errnop, herrnop, af,
flags))
== NSS_STATUS_SUCCESS)
@@ -336,15 +332,12 @@ _nss_files_gethostbyname3_r (const char
free (tmp_buffer);
}
- if (! keep_stream)
- internal_endent ();
+ internal_endent (&stream);
}
if (canonp && status == NSS_STATUS_SUCCESS)
*canonp = result->h_name;
- __libc_lock_unlock (lock);
-
return status;
}
@@ -373,16 +366,13 @@ _nss_files_gethostbyname4_r (const char
char *buffer, size_t buflen, int *errnop,
int *herrnop, int32_t *ttlp)
{
- __libc_lock_lock (lock);
+ FILE *stream = NULL;
- /* Reset file pointer to beginning or open file. */
- enum nss_status status = internal_setent (keep_stream);
+ /* Open file. */
+ enum nss_status status = internal_setent (&stream);
if (status == NSS_STATUS_SUCCESS)
{
- /* Tell getent function that we have repositioned the file pointer. */
- last_use = getby;
-
bool any = false;
bool got_canon = false;
while (1)
@@ -394,7 +384,7 @@ _nss_files_gethostbyname4_r (const char
buflen = buflen > pad ? buflen - pad : 0;
struct hostent result;
- status = internal_getent (&result, buffer, buflen, errnop,
+ status = internal_getent (stream, &result, buffer, buflen, errnop,
herrnop, AF_UNSPEC, 0);
if (status != NSS_STATUS_SUCCESS)
break;
@@ -470,8 +460,7 @@ _nss_files_gethostbyname4_r (const char
status = NSS_STATUS_SUCCESS;
}
- if (! keep_stream)
- internal_endent ();
+ internal_endent (&stream);
}
else if (status == NSS_STATUS_TRYAGAIN)
{
@@ -484,7 +473,5 @@ _nss_files_gethostbyname4_r (const char
*herrnop = NO_DATA;
}
- __libc_lock_unlock (lock);
-
return status;
}