Is there a file that always exists and a 'normal' user can't lstat it?

On modern Linux systems, you should be able to use /proc/1/fdinfo/0 (information for the file descriptor 1 (stdout) of the process of id 1 (init in the root pid namespace which should be running as root)).

You can find a list with (as a normal user):

sudo find /etc /dev /sys /proc -type f -print0 |
  perl -l -0ne 'print unless lstat'

(remove -type f if you don't want to restrict to regular files).

/var/cache/ldconfig/aux-cache is another potential candidate if you only need to consider Ubuntu systems. It should work on most GNU systems as /var/cache/ldconfig is created read+write+searchable to root only by the ldconfig command that comes with the GNU libc.


Looking at the lstat(2) man page you can get some inspiration on cases that might make it fail with errors other than ENOENT (file does not exist.)

The most obvious one is:

EACCES Search permission is denied for one of the directories in the path prefix of path.

So you need a directory you can't search from.

Yes, you can look for one that's already in your system (perhaps /var/lib/private if it exists?) But you might as well create one yourself, with the equivalent of:

$ mkdir myprivatedir
$ touch myprivatedir/myunreachablefile
$ chmod 0 myprivatedir
$ ls -l myprivatedir/myunreachablefile

The lstat(2) operation will fail with EACCES here. (Removing all permissions from the directory ensures that. Maybe you don't even need that much and chmod -x removing execute permissions would be enough, since execute permissions on a directory are needed to access files under it.)

There's another creative way to make lstat(2) fail, looking at its man page:

ENOTDIR A component of the path prefix of path is not a directory.

So, trying to access a file such as /etc/passwd/nonexistent should trigger this error, which again is different from ENOENT ("No such file or directory") and might suit your needs.

Another one is:

ENAMETOOLONG path is too long.

But you might need a really long name for this one (I believe 4,096 bytes is the typical limit, but your system/filesystem might have a longer one.)

Finally, it's hard to tell whether any of these will be actually useful for you. You say you want something that doesn't trigger the "file doesn't exist" scenario. While typically that means an ENOENT error, in practice many higher-level checks will simply interpret any errors from lstat(2) as "does not exist". For example test -e or the equivalent [ -e ...] from the shell might simply just interpret all of the above as "does not exist", especially since it doesn't have a good way to return a different error message and not returning an error would imply the file exists, which is most certainly not the case.


You can find it yourself.

Using /etc -- the configuration files directory as a starting point:

sudo find /etc -type f -perm 0400 -user root

On my system, this does not return anything.

You can be a less restrictive and allow group root (only user root should be a member of group root), and a look out for a permission of 440:

sudo find /etc -perm 0440 -user root -group root

On my system this returns:

/etc/sudoers.d/README
/etc/sudoers

Edit:

Based on your edit, you're looking for a directory that does not have sufficient permission for the invoking user to prevent directory listing:

sudo find / -perm o-rwx -type d -user root -group root 

here I'm looking for directories (-type d) that lack the read-write-execute perm bits for others (o-rwx) and is owned by root:root.

Technically, just the absense of execute (x) bit would prevent a directory listing (lstat(2)) on directory.

In the output I've found /run/systemd/inaccessible/ on my Systemd init based system.

Regarding files in /proc, /sys, /dev:

  • These filesystems are virtual FS i.e. they reside on memory, not on disk

  • If you plan to rely on /proc, use /proc/1/ i.e. rely on something under PID 1, not any later PIDs to have reliability/consistency as the later PIDs (processes) are not guaranteed to exist.