nss_compat: internal_end*ent may clobber errno, hiding ERANGE [BZ #25976]

Message ID 8736859uy8.fsf@oldenburg2.str.redhat.com
State Dropped
Headers
Series nss_compat: internal_end*ent may clobber errno, hiding ERANGE [BZ #25976] |

Commit Message

Florian Weimer May 12, 2020, 12:52 p.m. UTC
  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 May 14, 2020, 12:10 p.m. UTC | #1
* 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
  

Patch

diff --git a/nss/nss_compat/compat-grp.c b/nss/nss_compat/compat-grp.c
index 14aadc6f01..173c71abd5 100644
--- a/nss/nss_compat/compat-grp.c
+++ b/nss/nss_compat/compat-grp.c
@@ -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;
 }
 
diff --git a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c
index 67a4c100f6..60c8af64a3 100644
--- a/nss/nss_compat/compat-initgroups.c
+++ b/nss/nss_compat/compat-initgroups.c
@@ -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;
 }
 
diff --git a/nss/nss_compat/compat-pwd.c b/nss/nss_compat/compat-pwd.c
index dfb454f777..7fbce88e7e 100644
--- a/nss/nss_compat/compat-pwd.c
+++ b/nss/nss_compat/compat-pwd.c
@@ -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;
 }
 
diff --git a/nss/nss_compat/compat-spwd.c b/nss/nss_compat/compat-spwd.c
index 0a1fde1ea4..39eed87de8 100644
--- a/nss/nss_compat/compat-spwd.c
+++ b/nss/nss_compat/compat-spwd.c
@@ -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;
 }