Bug 161424 - [nullfs] __getcwd() calls fail when used on nullfs mount
Summary: [nullfs] __getcwd() calls fail when used on nullfs mount
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 8.2-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-fs (Nobody)
URL:
Keywords:
: 121898 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-10-09 15:00 UTC by Václav Haisman
Modified: 2018-05-28 19:44 UTC (History)
4 users (show)

See Also:


Attachments
file.txt (41.38 KB, text/plain)
2011-10-09 15:00 UTC, Václav Haisman
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Václav Haisman 2011-10-09 15:00:04 UTC
I am having problems with failing __getcwd() when the current directory is on nullfs mount:

 78028 valgrind CALL  execve(0x800a04070,0x7fffffffe530,0x800a05140)
 78028 valgrind NAMI  "/usr/local/lib/valgrind/memcheck-amd64-freebsd"
 78028 memcheck-amd64-free RET   execve 0
 78028 memcheck-amd64-free CALL  getpid
 78028 memcheck-amd64-free RET   getpid 78028/0x130cc
 78028 memcheck-amd64-free CALL  __sysctl(0x39a91450,0x4,0x389a3800,0x39a91468,0,0)
 78028 memcheck-amd64-free SCTL  "kern.proc.vmmap.78028"
 78028 memcheck-amd64-free RET   __sysctl 0
 78028 memcheck-amd64-free CALL  mmap(0x400009000,0x400000,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE|MAP_FIXED|MAP_ANON,0xffffffffffffffff,0)
 78028 memcheck-amd64-free RET   mmap 17179906048/0x400009000
 78028 memcheck-amd64-free CALL  getrlimit(RLIMIT_DATA,0x39e6a780)
 78028 memcheck-amd64-free RET   getrlimit 0
 78028 memcheck-amd64-free CALL  setrlimit(RLIMIT_DATA,0x39a919e0)
 78028 memcheck-amd64-free RET   setrlimit 0
 78028 memcheck-amd64-free CALL  getrlimit(RLIMIT_STACK,0x39e6a790)
 78028 memcheck-amd64-free RET   getrlimit 0
 78028 memcheck-amd64-free CALL  __getcwd(0x3882d700,0x3ff)
 78028 memcheck-amd64-free NAMI  ".."
 78028 memcheck-amd64-free RET   __getcwd -1 errno 2 No such file or directory

Cf. <http://docs.freebsd.org/cgi/getmsg.cgi?fetch=213231+0+archive/2011/freebsd-stable/20111009.freebsd-stable>

Fix: Patch attached with submission follows:
How-To-Repeat: shell::wilx:~/tmp/yttool> cd /usr/home/users/wilx/tmp/yttool
shell::wilx:/usr/home/users/wilx/tmp/yttool> valgrind --tool=memcheck ./yttool
==34679== Memcheck, a memory error detector
==34679== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==34679== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==34679== Command: ./yttool
==34679==
==34679==
==34679== HEAP SUMMARY:
==34679==     in use at exit: 20,395 bytes in 119 blocks
==34679==   total heap usage: 6,719 allocs, 6,600 frees, 716,787 bytes allocated
==34679==
==34679== LEAK SUMMARY:
==34679==    definitely lost: 0 bytes in 0 blocks
==34679==    indirectly lost: 0 bytes in 0 blocks
==34679==      possibly lost: 134 bytes in 4 blocks
==34679==    still reachable: 20,261 bytes in 115 blocks
==34679==         suppressed: 0 bytes in 0 blocks
==34679== Rerun with --leak-check=full to see details of leaked memory
==34679==
==34679== For counts of detected and suppressed errors, rerun with: -v
==34679== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
shell::wilx:/usr/home/users/wilx/tmp/yttool> cd $HOME/tmp/yttool
shell::wilx:~/tmp/yttool> valgrind --tool=memcheck ./yttool
valgrind: Startup or configuration error:
valgrind:    Can't establish current working directory at startup
valgrind: Unable to start up properly.  Giving up.
shell::wilx:~/tmp/yttool> mount
/dev/mfid0s3a on / (ufs, local, multilabel, acls)
devfs on /dev (devfs, local, multilabel)
/dev/ufs/tmpvol on /tmp (ufs, local, noatime, with quotas, soft-updates, multilabel, acls)
/dev/ufs/usrvol on /usr (ufs, local, with quotas, soft-updates, multilabel, acls)
/dev/ufs/varvol on /var (ufs, local, soft-updates, multilabel, acls)
procfs on /proc (procfs, local)
/usr/home/services/strojarna_data on /usr/home/services/strojarna/photos (nullfs, local)
/usr/home/services/strojarna_data on /usr/home/users/rizecek/public_html/strojarna/phpalbums/photos (nullfs, local)
/usr/home on /home (nullfs, local)
/usr/opt on /opt (nullfs, local)
linprocfs on /usr/compat/linux/proc (linprocfs, local)
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2011-10-10 06:10:06 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-fs

Over to maintainer(s).
Comment 2 Mateusz Guzik 2012-06-11 19:37:10 UTC
Hi,

are you able to reproduce this problem on FreeBSD 9.0?

Thanks,
-- 
Mateusz Guzik <mjguzik gmail.com>
Comment 3 Václav Haisman 2012-06-12 20:19:54 UTC
On 06/11/2012 08:37 PM, Mateusz Guzik wrote:
> Hi,
> 
> are you able to reproduce this problem on FreeBSD 9.0?
I cannot reproduce it right now but I do not have clean 9.0 release
available.

-- 
VZ
Comment 4 berend 2013-09-03 04:53:06 UTC
I have exactly the same problem in FreeBSD 9.1-RELEASE (almost, it runs
on AWS so some minor patches).

I have an ZFS pool, and nullfs mounted it. I wrote a simple C program
which exhibits the problem:

#include <stdio.h>
#include <errno.h>
#include <unistd.h>

int main () {
	void *r;
	char c[1024];
	r = getcwd(c, 1024);
	printf ("r = %p, errno = %i\n", r, errno);
	printf ("dir = %s\n", c);

}


Result:

r = 0x0, errno = 13
dir =

Very annoying, as I have my home directories on /u1/home and remount
them on /home to avoid having to rename a bunch of stuff.

All the best,

Berend.
Comment 5 berend 2014-02-18 00:42:17 UTC
Can report this is still a problem on FreeBSD 10.
Comment 6 Andriy Gapon freebsd_committer freebsd_triage 2014-02-19 10:30:51 UTC
Can you provide all the steps required to reproduce the problem?
The exact commands you execute to do mounting, to change to a directory, etc.

I can not reproduce the problem by just nullfs mounting one directory over
another, cd-ing into the mount and running your program.

-- 
Andriy Gapon
Comment 7 Jilles Tjoelker freebsd_committer freebsd_triage 2015-04-27 15:21:18 UTC
*** Bug 121898 has been marked as a duplicate of this bug. ***
Comment 8 berend 2015-07-05 21:41:29 UTC
Still happens on latest 10.1

To repeat you need to be an unprivileged user. As root I get:

    r = 0x7fffffffe690, errno = 2
    dir = /home/berend/sites/staging.xplainhosting.com

As user berend I get:

    r = 0x0, errno = 13
    dir = 

My setup: zpool name u1.

Mounted as:

    /u1/home on /home (nullfs, local)

Users reside in a postgresql which is made available via pam_pgsql and nss-pgsql.conf files. The latter appears to be inconsequential, because when a user is simply listed in /etc/passwd get the same error. For example this user:

    www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/bin/sh

I get:

    $ pwd
    /home/test
    # su www
    $ /tmp/a.out
    r = 0x0, errno = 13
    dir = 
    $ whoami
    www

Hope this helps.
Comment 9 fullermd 2015-08-14 10:17:19 UTC
I've just run into what looks like this (after lots of tracking and puzzled-looking) myself on a stable/10 system (in a jail, but it happens outside of jails too).

What's happening is that, when you're on a nullfs, if you don't have read permissions to all the directories in the path up to the root, it blows up, whereas on a regular FS, it does just fine.

e.g., I have a "/thome/matt/tmp/wt".  /thome and /thome/matt are root:wheel 751; the tmp/wt dirs are 755.  I use www as a convenient user, changing its shell to /bin/sh.

% (cd /thome/matt/tmp/wt ; su www -c /bin/pwd)
/thome/matt/tmp/wt

Yep, that's what it should get.  So then I null mount /thome off into /tmp:

% mount_nullfs /thome /tmp/th/

Then:

% ( cd /tmp/th/matt/tmp/wt ; su www -c /bin/pwd )
pwd: .: Permission denied

If I chmod 755 /thome and /thome/matt, then

% ( cd /tmp/th/matt/tmp/wt ; su www -c /bin/pwd )
/tmp/th/matt/tmp/wt
Comment 10 Konstantin Belousov freebsd_committer freebsd_triage 2015-08-14 13:01:16 UTC
(In reply to fullermd from comment #9)
What you described is the expected behaviour, it is just a situation that it always happens for nullfs, but only sporadically for other filesystems.

More precisely, nullfs does not use namecache for good reasons (we cannot provide cache consistency between nullfs entries and lower filesystems without some drastic measures).  If a filesystem uses namecache, then getcwd call first tries to resolve the path using namecache, and only when the cache failed to provide an entry, it falls down to read the ".." directory and searching the child entry name by inode number.  So typically for fs like ufs or zfs, the reading of ".." does not happen.

On the other hand, since nullfs does not use namecache, ".." is always scanned and there the directory permissions starts to play.

So the fix, if we ever would change the observed behaviour, is to make getcwd to honor the directory permissions even when the request is satisfied by the namecache, making failure deterministic.
Comment 11 Eitan Adler freebsd_committer freebsd_triage 2018-05-28 19:44:45 UTC
batch change:

For bugs that match the following
-  Status Is In progress 
AND
- Untouched since 2018-01-01.
AND
- Affects Base System OR Documentation

DO:

Reset to open status.


Note:
I did a quick pass but if you are getting this email it might be worthwhile to double check to see if this bug ought to be closed.