Bug 2418 - getcwd() print an assertion for a path greater than MAX_PATH
Summary: getcwd() print an assertion for a path greater than MAX_PATH
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.3.6
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-03-05 17:02 UTC by Aurelien Jarno
Modified: 2018-04-19 13:50 UTC (History)
1 user (show)

See Also:
Host: ia64-unknown-linux-gnu
Target: ia64-unknown-linux-gnu
Build: ia64-unknown-linux-gnu
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Aurelien Jarno 2006-03-05 17:02:01 UTC
Here is the code which causes problem, in sysdeps/unix/sysv/linux/getcwd.c :

      /* It should never happen that the `getcwd' syscall failed because
         the buffer is too small if we allocated the buffer ourselves
         large enough.  */
      assert (errno != ERANGE || buf != NULL || size != 0);

The buffer allocated by the code before is of size MAX_PATH. So if the actual
size of the path on the filesystem is greater than MAX_PATH, an assertion is
printed.

That proves that it could happen! I suggest simply removing the assertion, as
the function then just exits with the error code.

Note that the problem only occurs on ia64, on other platforms the error number
returned is ENAMETOOLONG (see bug 2417)
Comment 1 Ulrich Drepper 2006-04-01 20:59:15 UTC
Removing assert is almost never good.  Provide a test case.  Note that neither
the libc or kernel side of getcwd is architecture-speicfic.  Otherwise I'll just
close the bug.
Comment 2 Aurelien Jarno 2006-04-01 21:38:25 UTC
(In reply to comment #1) 
> Removing assert is almost never good.  Provide a test case.  Note that 
neither 
> the libc or kernel side of getcwd is architecture-speicfic.  Otherwise I'll 
just 
> close the bug. 
 
I haven't found the time to look more at this bug, however LaMont Jones sent me  
a more detailed analysis of the problem: 
 
Actually, it will occur on any machine that has PAGE_SIZE >> PATH_MAX 
 
Possible workarounds for coreutils:  Use a path of more than 16384 
bytes in length for the test, rather than just more than 4096.  :-)  
 
For glibc:  The assertion is bogus.  In fact, the path in question from 
this test is more than PATH_MAX bytes in length.  Because 
PAGE_SIZE==PATH_MAX, sys_getcwd returns ENAMETOOLONG (since it can't 
construct the path in the buffer it's using internally), while ia64 has 
enough room to build a path (up to 16K), but not enough room to return 
it in the malloced buffer from getcwd(3). 
 
The correct solution is, of course, to copy the code from the readlink 
loop immediately below the assert to realloc until it fits.  OTOH, 
the diff below makes it behave the same as it does today on all 
machines. 
 
--- sysdeps/unix/sysv/linux/getcwd.c.orig	2003-09-19 19:05:49.000000000 
-0600 
+++ sysdeps/unix/sysv/linux/getcwd.c	2006-03-23 16:11:04.000000000 -0700 
@@ -124,10 +124,11 @@ 
 	} 
  
 # if __ASSUME_GETCWD_SYSCALL 
-      /* It should never happen that the `getcwd' syscall failed because 
-	 the buffer is too small if we allocated the buffer ourselves 
-	 large enough.  */ 
-      assert (errno != ERANGE || buf != NULL || size != 0); 
+      /* It is possible that the `getcwd' syscall failed because 
+	 the buffer is too small even though we allocaed MAX_PATH 
+	 bytes.  if PAGE_SIZE != PATH_MAX, then we can get back ERANGE 
+	 instead of ENAMETOOLONG in this case. */ 
+      /* assert (errno != ERANGE || buf != NULL || size != 0); */ 
  
 #  ifndef NO_ALLOCATION 
       if (buf == NULL) 
 
Comment 3 Aurelien Jarno 2006-04-01 21:40:05 UTC
(In reply to comment #2) 
> (In reply to comment #1)  
> > Removing assert is almost never good.  Provide a test case.  Note that  
> neither  
> > the libc or kernel side of getcwd is architecture-speicfic.  Otherwise I'll  
> just  
> > close the bug.  
>   
 
For the testcase, just try to build a recent coreutils (for example 5.94) on an 
ia64 machine. The testsuite will fail. 
Comment 4 Andreas Schwab 2006-04-01 21:51:49 UTC
See <http://sourceware.org/ml/libc-hacker/2005-11/msg00001.html>.
Comment 5 Ulrich Drepper 2006-04-02 17:59:47 UTC
Andreas' patch is of course much better.  Working around an assert is never the
right idea.  I added an MAX in there, though, just in case somebody does
something stupid wrt to the definitions.