Bug 22157 - getcwd() returns EINVAL(22) instead of ENOENT
Summary: getcwd() returns EINVAL(22) instead of ENOENT
Status: RESOLVED DUPLICATE of bug 17924
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-19 13:53 UTC by Dhiraj Kumar
Modified: 2023-12-29 11:11 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
Test Program and strace log (22.76 KB, application/x-compressed-tar)
2017-09-19 13:53 UTC, Dhiraj Kumar
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dhiraj Kumar 2017-09-19 13:53:47 UTC
Created attachment 10431 [details]
Test Program and strace log

Hi,

Sometimes getcwd() returns EINVAL error instead of ENOENT.

I have come accross a scenario like below,

Under Test Program, mlockall(MCL_FUTURE)  is called and after that repeatedly  getcwd(NULL, 66000)  is called and "errno" is checked if getcwd() returns NULL.

Now, under script below steps are executed,


################
count=1
maxcount=999999
	
mkdir  thr_getcwd_testdir/
cd  thr_getcwd_testdir/
rm -rf  ../thr_getcwd_testdir/

while [ $count -le $maxcount ];
do
  ../thr_getcwd  ===>>> program which calls mlockall() and then getcwd(()
  if [ "$?" != "0" ] ; then
      exit 1
  fi
done
################


Here, current directory is deleted but it's handle is still present.
What is expected is getcwd() should have set errno to ENOENT but errno
is set to EINVAL.

After going through the glibc code flow looks like below,

getcwd() 
   => __getcwd() => malloc() 
   => getcwd()[syscall] ---> This sets errno as ENOENT.
   => free() => __libc_free() => _int_free() => heap_trim() 
   => shrink_heap() => __madvise() 
   => madvise()[syscall] ---> This sets errno as EINVAL because of mlockall().

So eventhough getcwd() sets correct errono but madvise() changes that and due to that application receives wrong errno.

Same is confirmed via strace, which is attached with the bug.
       $ strace  -f  -o  strace.txt  ./thr_getcwd.sh

We have even attached Test Program to reproduce the issue.

Running test program,
	$ tar -xzvf  thr_getcwd.tgz
	$ ./thr_getcwd.sh
		
Please suggest if above scenario should be considered as bug or not.


Thanks!
Dhiraj
Comment 1 Florian Weimer 2017-09-19 21:02:11 UTC
It's a bug that free sets errno.  Thanks for pointing out another scenario for that.

*** This bug has been marked as a duplicate of bug 17924 ***