nss_compat: internal_end*ent may clobber errno, hiding ERANGE [BZ #25976]
Commit Message
Change the internal_end*ent functions to preserve errno because they
are called on error-returning paths, where the value of errno matters.
For the external-facing _nss_compat_end*ent functions, this is not
required because they always report success, so they may clobber
errno.
-----
nss/nss_compat/compat-grp.c | 3 +++
nss/nss_compat/compat-initgroups.c | 3 +++
nss/nss_compat/compat-pwd.c | 3 +++
nss/nss_compat/compat-spwd.c | 3 +++
4 files changed, 12 insertions(+)
Comments
* Florian Weimer via Libc-alpha:
> Change the internal_end*ent functions to preserve errno because they
> are called on error-returning paths, where the value of errno matters.
>
> For the external-facing _nss_compat_end*ent functions, this is not
> required because they always report success, so they may clobber
> errno.
Internal discussion at Red Hat convinced me that the patch does not go
into the right direction, so I'm withdrawing it for now.
Thanks,
Florian
@@ -147,6 +147,8 @@ _nss_compat_setgrent (int stayopen)
static enum nss_status
internal_endgrent (ent_t *ent)
{
+ int saved_errno = errno;
+
if (ent->stream != NULL)
{
fclose (ent->stream);
@@ -162,6 +164,7 @@ internal_endgrent (ent_t *ent)
else
ent->blacklist.current = 0;
+ __set_errno (saved_errno);
return NSS_STATUS_SUCCESS;
}
@@ -137,6 +137,8 @@ internal_setgrent (ent_t *ent)
static enum nss_status
internal_endgrent (ent_t *ent)
{
+ int saved_errno = errno;
+
if (ent->stream != NULL)
{
fclose (ent->stream);
@@ -155,6 +157,7 @@ internal_endgrent (ent_t *ent)
if (ent->need_endgrent && endgrent_impl != NULL)
endgrent_impl ();
+ __set_errno (saved_errno);
return NSS_STATUS_SUCCESS;
}
@@ -264,6 +264,8 @@ _nss_compat_setpwent (int stayopen)
static enum nss_status
internal_endpwent (ent_t *ent)
{
+ int saved_errno = errno;
+
if (ent->stream != NULL)
{
fclose (ent->stream);
@@ -286,6 +288,7 @@ internal_endpwent (ent_t *ent)
give_pwd_free (&ent->pwd);
+ __set_errno (saved_errno);
return NSS_STATUS_SUCCESS;
}
@@ -220,6 +220,8 @@ _nss_compat_setspent (int stayopen)
static enum nss_status
internal_endspent (ent_t *ent)
{
+ int saved_errno = errno;
+
if (ent->stream != NULL)
{
fclose (ent->stream);
@@ -243,6 +245,7 @@ internal_endspent (ent_t *ent)
give_spwd_free (&ent->pwd);
+ __set_errno (saved_errno);
return NSS_STATUS_SUCCESS;
}