]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Correctly handle buffer overflow while reading line with fgets.
authorUlrich Drepper <drepper@redhat.com>
Fri, 30 Jan 1998 17:20:29 +0000 (17:20 +0000)
committerUlrich Drepper <drepper@redhat.com>
Fri, 30 Jan 1998 17:20:29 +0000 (17:20 +0000)
grp/fgetgrent_r.c
nis/nss_compat/compat-grp.c
nis/nss_compat/compat-pwd.c
nis/nss_compat/compat-spwd.c
nss/nss_files/files-XXX.c
nss/nss_files/files-alias.c
pwd/fgetpwent_r.c
shadow/fgetspent_r.c

index 44298c5ba60c46c92d2b70d2dcd280a066de5a99..1a37e0477c3a309a3c5f1b5b0fe5699647ab83b7 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -60,12 +60,18 @@ __fgetgrent_r (FILE *stream, struct group *resbuf, char *buffer, size_t buflen,
 
   do
     {
+      buffer[buflen] = '\xff';
       p = fgets (buffer, buflen, stream);
-      if (p == NULL)
+      if (p == NULL && feof (stream))
        {
          *result = NULL;
          return errno;
        }
+      if (p == NULL || buffer[buflen] != '\xff')
+       {
+         *result = NULL;
+         return errno = ERANGE;
+       }
 
       /* Skip leading blanks.  */
       while (isspace (*p))
index 91a19c0b7740c8e423fb3d200b44e94ba66ce02c..693ade575e6bced9ac3c97af6ead442cc919ce77 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
 
@@ -315,17 +315,15 @@ getgrent_next_file (struct group *result, ent_t *ent,
       do
        {
          fgetpos (ent->stream, &pos);
+         buffer[buflen - 1] = '\xff';
          p = fgets (buffer, buflen, ent->stream);
-         if (p == NULL)
+         if (p == NULL && feof (ent->stream))
+           return NSS_STATUS_NOTFOUND;
+         if (p == NULL || buffer[buflen - 1] != '\xff')
            {
-             if (feof (ent->stream))
-               return NSS_STATUS_NOTFOUND;
-             else
-               {
-                 fsetpos (ent->stream, &pos);
-                 __set_errno (ERANGE);
-                 return NSS_STATUS_TRYAGAIN;
-               }
+             fsetpos (ent->stream, &pos);
+             __set_errno (ERANGE);
+             return NSS_STATUS_TRYAGAIN;
            }
 
          /* Terminate the line for any case.  */
@@ -446,17 +444,15 @@ internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
       do
        {
          fgetpos (ent->stream, &pos);
+         buffer[buflen - 1] = '\xff';
          p = fgets (buffer, buflen, ent->stream);
-         if (p == NULL)
+         if (p == NULL && feof (ent->stream))
+           return NSS_STATUS_NOTFOUND;
+         if (p == NULL || buffer[buflen - 1] != '\xff')
            {
-             if (feof (ent->stream))
-               return NSS_STATUS_NOTFOUND;
-             else
-               {
-                 fsetpos (ent->stream, &pos);
-                 __set_errno (ERANGE);
-                 return NSS_STATUS_TRYAGAIN;
-               }
+             fsetpos (ent->stream, &pos);
+             __set_errno (ERANGE);
+             return NSS_STATUS_TRYAGAIN;
            }
 
          /* Terminate the line for any case.  */
@@ -607,17 +603,15 @@ internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
       do
        {
          fgetpos (ent->stream, &pos);
+         buffer[buflen - 1] = '\xff';
          p = fgets (buffer, buflen, ent->stream);
-         if (p == NULL)
+         if (p == NULL && feof (ent->stream))
+           return NSS_STATUS_NOTFOUND;
+         if (p == NULL || buffer[buflen - 1] != '\xff')
            {
-             if (feof (ent->stream))
-               return NSS_STATUS_NOTFOUND;
-             else
-               {
-                 fsetpos (ent->stream, &pos);
-                 __set_errno (ERANGE);
-                 return NSS_STATUS_TRYAGAIN;
-               }
+             fsetpos (ent->stream, &pos);
+             __set_errno (ERANGE);
+             return NSS_STATUS_TRYAGAIN;
            }
 
          /* Terminate the line for any case.  */
index afc35e2cfd2ce10f9a4cf4104730884aff7d6f8e..6b1712e5b77adaa15ceaece43f7e5239c5d1cc63 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
 
@@ -565,17 +565,15 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
       do
        {
          fgetpos (ent->stream, &pos);
+         buffer[buflen - 1] = '\xff';
          p = fgets (buffer, buflen, ent->stream);
-         if (p == NULL)
+         if (p == NULL && feof (ent->stream))
+           return NSS_STATUS_NOTFOUND;
+         if (p == NULL || buffer[buflen - 1] != '\xff')
            {
-             if (feof (ent->stream))
-               return NSS_STATUS_NOTFOUND;
-             else
-               {
-                 fsetpos (ent->stream, &pos);
-                 __set_errno (ERANGE);
-                 return NSS_STATUS_TRYAGAIN;
-               }
+             fsetpos (ent->stream, &pos);
+             __set_errno (ERANGE);
+             return NSS_STATUS_TRYAGAIN;
            }
 
          /* Terminate the line for any case.  */
@@ -745,17 +743,15 @@ internal_getpwnam_r (const char *name, struct passwd *result, ent_t *ent,
       do
        {
          fgetpos (ent->stream, &pos);
+         buffer[buflen - 1] = '\xff';
          p = fgets (buffer, buflen, ent->stream);
-         if (p == NULL)
+         if (p == NULL && feof (ent->stream))
+           return NSS_STATUS_NOTFOUND;
+         if (p == NULL || buffer[buflen - 1] != '\xff')
            {
-             if (feof (ent->stream))
-               return NSS_STATUS_NOTFOUND;
-             else
-               {
-                 fsetpos (ent->stream, &pos);
-                 __set_errno (ERANGE);
-                 return NSS_STATUS_TRYAGAIN;
-               }
+             fsetpos (ent->stream, &pos);
+             __set_errno (ERANGE);
+             return NSS_STATUS_TRYAGAIN;
            }
 
          /* Terminate the line for any case.  */
@@ -982,17 +978,15 @@ internal_getpwuid_r (uid_t uid, struct passwd *result, ent_t *ent,
       do
        {
          fgetpos (ent->stream, &pos);
+         buffer[buflen - 1] = '\xff';
          p = fgets (buffer, buflen, ent->stream);
-         if (p == NULL)
+         if (p == NULL && feof (ent->stream))
+           return NSS_STATUS_NOTFOUND;
+         if (p == NULL || buffer[buflen - 1] != '\xff')
            {
-             if (feof (ent->stream))
-               return NSS_STATUS_NOTFOUND;
-             else
-               {
-                 fsetpos (ent->stream, &pos);
-                 __set_errno (ERANGE);
-                 return NSS_STATUS_TRYAGAIN;
-               }
+             fsetpos (ent->stream, &pos);
+             __set_errno (ERANGE);
+             return NSS_STATUS_TRYAGAIN;
            }
 
          /* Terminate the line for any case.  */
index 76ce8831e75e2b39aa355a7fd013c252a6082afc..007305c42487b1480ccf6c7d3b4ef9495fa07674 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
 
@@ -515,9 +515,16 @@ getspent_next_file (struct spwd *result, ent_t *ent,
       do
        {
          fgetpos (ent->stream, &pos);
+         buffer[buflen - 1] = '\xff';
          p = fgets (buffer, buflen, ent->stream);
-         if (p == NULL)
+         if (p == NULL && feof (ent->stream))
            return NSS_STATUS_NOTFOUND;
+         if (p == NULL || buffer[buflen - 1] != '\xff')
+           {
+             fsetpos (ent->stream, &pos);
+             __set_errno (ERANGE);
+             return NSS_STATUS_TRYAGAIN;
+           }
 
          /* Terminate the line for any case.  */
          buffer[buflen - 1] = '\0';
@@ -690,9 +697,16 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
       do
        {
          fgetpos (ent->stream, &pos);
+         buffer[buflen - 1] = '\xff';
          p = fgets (buffer, buflen, ent->stream);
-         if (p == NULL)
+         if (p == NULL && feof (ent->stream))
            return NSS_STATUS_NOTFOUND;
+         if (p == NULL || buffer[buflen - 1] != '\xff')
+           {
+             fsetpos (ent->stream, &pos);
+             __set_errno (ERANGE);
+             return NSS_STATUS_TRYAGAIN;
+           }
 
          /* Terminate the line for any case.  */
          buffer[buflen - 1] = '\0';
index ac6b5fa94a8c160ddfcc52cd2c3fb9e6e9a5f198..b36a8b97157767920fe9ec91c6fe39d3e3baefba 100644 (file)
@@ -1,5 +1,5 @@
 /* Common code for file-based databases in nss_files module.
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -179,16 +179,16 @@ internal_getent (struct STRUCTURE *result,
   do
     {
       /* Terminate the line so that we can test for overflow.  */
-      data->linebuffer[linebuflen - 1] = '\0';
+      data->linebuffer[linebuflen - 1] = '\xff';
 
       p = fgets (data->linebuffer, linebuflen, stream);
-      if (p == NULL)
+      if (p == NULL && feof (stream))
        {
          /* End of file or read error.  */
          H_ERRNO_SET (HOST_NOT_FOUND);
          return NSS_STATUS_NOTFOUND;
        }
-      else if (data->linebuffer[linebuflen - 1] != '\0')
+      else if (p == NULL || data->linebuffer[linebuflen - 1] != '\xff')
        {
          /* The line is too long.  Give the user the opportunity to
             enlarge the buffer.  */
index aca89ed73c23efe40be899c3af52fc18b9c4e7d8..dda203531735dab4f2830f76de4d270af363bbe0 100644 (file)
@@ -1,5 +1,5 @@
 /* Mail alias file parser in nss_files module.
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -150,12 +150,12 @@ get_next_alias (const char *match, struct aliasent *result,
 
       /* Read the first line.  It must contain the alias name and
         possibly some alias names.  */
-      first_unused[room_left - 1] = '\0';
+      first_unused[room_left - 1] = '\xff';
       line = fgets (first_unused, room_left, stream);
-      if (line == NULL)
+      if (line == NULL && feof (stream))
        /* Nothing to read.  */
        break;
-      else if (first_unused[room_left - 1] != '\0')
+      else if (line == NULL || first_unused[room_left - 1] != '\xff')
        {
          /* The line is too long for our buffer.  */
        no_more_room:
@@ -200,7 +200,8 @@ get_next_alias (const char *match, struct aliasent *result,
             looking for.  If it does not match we simply ignore all
             lines until the next line containing the start of a new
             alias is found.  */
-         ignore = match != NULL && strcmp (result->alias_name, match) != 0;
+         ignore = (match != NULL
+                   && __strcasecmp (result->alias_name, match) != 0);
 
          while (! ignore)
            {
@@ -243,11 +244,12 @@ get_next_alias (const char *match, struct aliasent *result,
                        {
                          while (! feof (listfile))
                            {
-                             first_unused[room_left - 1] = '\0';
+                             first_unused[room_left - 1] = '\xff';
                              line = fgets (first_unused, room_left, listfile);
-                             if (line == NULL)
+                             if (line == NULL && feof (listfile))
                                break;
-                             if (first_unused[room_left - 1] != '\0')
+                             if (line == NULL
+                                 || first_unused[room_left - 1] != '\xff')
                                {
                                  free (old_line);
                                  goto no_more_room;
@@ -343,9 +345,11 @@ get_next_alias (const char *match, struct aliasent *result,
 
                  /* The just read character is a white space and so
                     can be ignored.  */
-                 first_unused[room_left - 1] = '\0';
+                 first_unused[room_left - 1] = '\xff';
                  line = fgets (first_unused, room_left, stream);
-                 if (first_unused[room_left - 1] != '\0')
+                 if (line == NULL && feof (stream))
+                   break;
+                 if (line == NULL || first_unused[room_left - 1] != '\xff')
                    goto no_more_room;
                  cp = strpbrk (line, "#\n");
                  if (cp != NULL)
index 9bf33976756033265b5d99127a0b2c786fc4bbce..7f95a1a40edd1522dcef0cb7c2d7e4e89236f2bd 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -73,12 +73,18 @@ __fgetpwent_r (FILE *stream, struct passwd *resbuf, char *buffer,
 
   do
     {
+      buffer[buflen] = '\xff';
       p = fgets (buffer, buflen, stream);
-      if (p == NULL)
+      if (p == NULL && feof (stream))
        {
          *result = NULL;
          return errno;
        }
+      if (p == NULL || buffer[buflen] != '\xff')
+       {
+         *result = NULL;
+         return errno = ERANGE;
+       }
 
       /* Skip leading blanks.  */
       while (isspace (*p))
index 403eecf76102463b9549e3f93eb0b8b32d9a2733..fc9dedea24f79a90967ee5ca0c195a60761388bb 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -40,12 +40,18 @@ __fgetspent_r (FILE *stream, struct spwd *resbuf, char *buffer, size_t buflen,
 
   do
     {
+      buffer[buflen - 1] = '\xff';
       p = fgets (buffer, buflen, stream);
-      if (p == NULL)
+      if (p == NULL && feof (stream))
        {
          *result = NULL;
          return errno;
        }
+      if (p == NULL || buffer[buflen] != '\xff')
+       {
+         *result = NULL;
+         return errno = ERANGE;
+       }
 
       /* Skip leading blanks.  */
       while (isspace (*p))