Commit 16e60fff by Janne Blomqvist

Fix stack overflow crash in getcwd intrinsic.

2014-05-12  Janne Blomqvist  <jb@gcc.gnu.org>

	PR libfortran/61035
	* intrinsics/getcwd.c (getcwd_i4_sub): Avoid potentially large
	stack allocation, avoid extra copying in the common case.

From-SVN: r210335
parent f7b6856f
2014-05-12 Janne Blomqvist <jb@gcc.gnu.org> 2014-05-12 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/61035
* intrinsics/getcwd.c (getcwd_i4_sub): Avoid potentially large
stack allocation, avoid extra copying in the common case.
2014-05-12 Janne Blomqvist <jb@gcc.gnu.org>
* configure.ac (AM_CFLAGS): Use -std=gnu11. * configure.ac (AM_CFLAGS): Use -std=gnu11.
(CFLAGS): Likewise. (CFLAGS): Likewise.
* configure: Regenerated. * configure: Regenerated.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Copyright (C) 2004-2014 Free Software Foundation, Inc. Copyright (C) 2004-2014 Free Software Foundation, Inc.
Contributed by Steven G. Kargl <kargls@comcast.net>. Contributed by Steven G. Kargl <kargls@comcast.net>.
This file is part of the GNU Fortran 95 runtime library (libgfortran). This file is part of the GNU Fortran runtime library (libgfortran).
Libgfortran is free software; you can redistribute it and/or Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public modify it under the terms of the GNU General Public
...@@ -40,20 +40,35 @@ iexport_proto(getcwd_i4_sub); ...@@ -40,20 +40,35 @@ iexport_proto(getcwd_i4_sub);
void void
getcwd_i4_sub (char *cwd, GFC_INTEGER_4 *status, gfc_charlen_type cwd_len) getcwd_i4_sub (char *cwd, GFC_INTEGER_4 *status, gfc_charlen_type cwd_len)
{ {
char str[cwd_len + 1]; int err;
GFC_INTEGER_4 stat;
memset(cwd, ' ', (size_t) cwd_len); if (getcwd (cwd, cwd_len))
if (!getcwd (str, (size_t) cwd_len + 1))
stat = errno;
else
{ {
stat = 0; size_t len = strlen (cwd);
memcpy (cwd, str, strlen (str)); memset (cwd + len, ' ', cwd_len - len);
err = 0;
} }
else if (errno == ERANGE)
{
/* There is a possibility that the previous attempt failed due
to not enough space for the terminating null byte. Try again
with a buffer one char longer. */
char *buf = xmalloc (cwd_len + 1);
if (getcwd (buf, cwd_len + 1))
{
memcpy (cwd, buf, cwd_len);
err = 0;
}
else
err = errno;
free (buf);
}
else
err = errno;
if (err)
memset (cwd, ' ', cwd_len);
if (status != NULL) if (status != NULL)
*status = stat; *status = err;
} }
iexport(getcwd_i4_sub); iexport(getcwd_i4_sub);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment