about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--NEWS2
-rw-r--r--misc/Makefile3
-rw-r--r--misc/mntent_r.c4
-rw-r--r--misc/tst-mntent-blank-corrupt.c45
-rw-r--r--misc/tst-mntent-blank-passno.c53
-rw-r--r--misc/tst-mntent.c20
7 files changed, 114 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 61e667158d..9aa8f51d88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2015-08-28  Mike Frysinger  <vapier@gentoo.org>
+
+	[BZ #18887]
+	* misc/Makefile (tests): Add tst-mntent-blank-corrupt and
+	tst-mntent-blank-passno.
+	* misc/mntent_r.c (__getmntent_r): Do not read past buffer[0].
+	* misc/tst-mntent-blank-corrupt.c: New test.
+	* misc/tst-mntent-blank-passno.c: New test ripped from ...
+	* misc/tst-mntent.c (do_test): ... here.
+
 2015-07-27  Mike Frysinger  <vapier@gentoo.org>
 
 	* sysdeps/ia64/bits/atomic.h (atomic_exchange_and_add): Define
diff --git a/NEWS b/NEWS
index e3588fce7a..52116d585a 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.21.1
 
 * The following bugs are resolved with this release:
 
-  17269, 17949, 18032, 18287, 18694.
+  17269, 17949, 18032, 18287, 18694, 18887.
 
 * A buffer overflow in gethostbyname_r and related functions performing DNS
   requests has been fixed.  If the NSS functions were called with a
diff --git a/misc/Makefile b/misc/Makefile
index aecb0dae9d..2f5edf6316 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -76,7 +76,8 @@ install-lib := libg.a
 gpl2lgpl := error.c error.h
 
 tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
-	 tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
+	 tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \
+	 tst-mntent-blank-corrupt tst-mntent-blank-passno
 ifeq ($(run-built-tests),yes)
 tests-special += $(objpfx)tst-error1-mem.out
 endif
diff --git a/misc/mntent_r.c b/misc/mntent_r.c
index 615987347a..4f269984d7 100644
--- a/misc/mntent_r.c
+++ b/misc/mntent_r.c
@@ -136,7 +136,9 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
       end_ptr = strchr (buffer, '\n');
       if (end_ptr != NULL)	/* chop newline */
 	{
-	  while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')
+	  /* Do not walk past the start of buffer if it's all whitespace.  */
+	  while (end_ptr != buffer
+		 && (end_ptr[-1] == ' ' || end_ptr[-1] == '\t'))
             end_ptr--;
 	  *end_ptr = '\0';
 	}
diff --git a/misc/tst-mntent-blank-corrupt.c b/misc/tst-mntent-blank-corrupt.c
new file mode 100644
index 0000000000..92266a35b5
--- /dev/null
+++ b/misc/tst-mntent-blank-corrupt.c
@@ -0,0 +1,45 @@
+/* Make sure blank lines does not cause memory corruption BZ #18887.
+
+   Copyright (C) 2009-2015 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <mntent.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Make sure blank lines don't trigger memory corruption.  This doesn't happen
+   for all targets though, so it's a best effort test BZ #18887.  */
+static int
+do_test (void)
+{
+  FILE *fp;
+
+  fp = tmpfile ();
+  fputs ("\n \n/foo\\040dir /bar\\040dir auto bind \t \n", fp);
+  rewind (fp);
+
+  /* The corruption happens here ...  */
+  getmntent (fp);
+  /* ... but trigers here.  */
+  endmntent (fp);
+
+  /* If the test failed, we would crash, and not hit this point.  */
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/misc/tst-mntent-blank-passno.c b/misc/tst-mntent-blank-passno.c
new file mode 100644
index 0000000000..fc0429197f
--- /dev/null
+++ b/misc/tst-mntent-blank-passno.c
@@ -0,0 +1,53 @@
+/* Make sure trailing whitespace is handled properly BZ #17273.
+
+   Copyright (C) 2009-2015 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <mntent.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Check entries to make sure trailing whitespace is ignored and we return the
+   correct passno value BZ #17273.  */
+static int
+do_test (void)
+{
+  int result = 0;
+  FILE *fp;
+  struct mntent *mnt;
+
+  fp = tmpfile ();
+  fputs ("/foo\\040dir /bar\\040dir auto bind \t \n", fp);
+  rewind (fp);
+
+  mnt = getmntent (fp);
+  if (strcmp (mnt->mnt_fsname, "/foo dir") != 0
+      || strcmp (mnt->mnt_dir, "/bar dir") != 0
+      || strcmp (mnt->mnt_type, "auto") != 0
+      || strcmp (mnt->mnt_opts, "bind") != 0
+      || mnt->mnt_freq != 0
+      || mnt->mnt_passno != 0)
+    {
+      puts ("Error while reading entry with trailing whitespaces");
+      result = 1;
+    }
+
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/misc/tst-mntent.c b/misc/tst-mntent.c
index 876c89f8ed..820b35493b 100644
--- a/misc/tst-mntent.c
+++ b/misc/tst-mntent.c
@@ -73,26 +73,6 @@ main (int argc, char *argv[])
 	  puts ("Error while reading written entry back in");
 	  result = 1;
 	}
-
-      /* Part III: Entry with whitespaces at the end of a line. */
-      rewind (fp);
-
-      fputs ("/foo\\040dir /bar\\040dir auto bind \t \n", fp);
-
-      rewind (fp);
-
-      mnt = getmntent (fp);
-
-      if (strcmp (mnt->mnt_fsname, "/foo dir") != 0
-	  || strcmp (mnt->mnt_dir, "/bar dir") != 0
-	  || strcmp (mnt->mnt_type, "auto") != 0
-	  || strcmp (mnt->mnt_opts, "bind") != 0
-	  || mnt->mnt_freq != 0
-	  || mnt->mnt_passno != 0)
-	{
-	  puts ("Error while reading entry with trailing whitespaces");
-	  result = 1;
-	}
    }
 
   return result;