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












14















I need this for a unit test. There's a function that does lstat on the file path passed as its parameter. I have to trigger the code path where the lstat fails (because the code coverage has to reach 90%)



The test can run only under a single user, therefore I was wondering if there's a file in Ubuntu that always exists, but normal users have no read access to it, or to its folder. (So lstat would fail on it unless executed as root.)



A non-existent file is not a solution, because there's a separate code path for that, which I'm already triggering.



EDIT: Lack of read access to the file only is not enough. With that lstat can still be executed. I was able to trigger it (on my local machine, where I have root access), by creating a folder in /root, and a file in it. And setting permission 700 on the folder. So I'm searching for a file that is in a folder that is only accessible by root.










share|improve this question




















  • 6





    IMHO /etc/shadow

    – Romeo Ninov
    Feb 25 at 11:52






  • 3





    You cannot assume the existence of any file, because your program may run in a chroot or separate namespace. If assuming that /proc is mounted is OK and init is nothing special, then /proc/1/fd/0 should do.

    – mosvy
    Feb 25 at 12:12








  • 1





    @mosvy Thanks that works on my local machine. Hmm then I'll try it on the QA and Staging pool too.

    – Crouching Kitten
    Feb 25 at 12:15






  • 2





    Why are you tying your test code to a particular flavor of OS when you could just create a throwaway file and remove your own read access to it?

    – Kilian Foth
    Feb 25 at 16:05






  • 4





    I'd argue that it's not really a unit test once it starts depending on a real, rather than mocked, filesystem.

    – Toby Speight
    Feb 25 at 17:05
















14















I need this for a unit test. There's a function that does lstat on the file path passed as its parameter. I have to trigger the code path where the lstat fails (because the code coverage has to reach 90%)



The test can run only under a single user, therefore I was wondering if there's a file in Ubuntu that always exists, but normal users have no read access to it, or to its folder. (So lstat would fail on it unless executed as root.)



A non-existent file is not a solution, because there's a separate code path for that, which I'm already triggering.



EDIT: Lack of read access to the file only is not enough. With that lstat can still be executed. I was able to trigger it (on my local machine, where I have root access), by creating a folder in /root, and a file in it. And setting permission 700 on the folder. So I'm searching for a file that is in a folder that is only accessible by root.










share|improve this question




















  • 6





    IMHO /etc/shadow

    – Romeo Ninov
    Feb 25 at 11:52






  • 3





    You cannot assume the existence of any file, because your program may run in a chroot or separate namespace. If assuming that /proc is mounted is OK and init is nothing special, then /proc/1/fd/0 should do.

    – mosvy
    Feb 25 at 12:12








  • 1





    @mosvy Thanks that works on my local machine. Hmm then I'll try it on the QA and Staging pool too.

    – Crouching Kitten
    Feb 25 at 12:15






  • 2





    Why are you tying your test code to a particular flavor of OS when you could just create a throwaway file and remove your own read access to it?

    – Kilian Foth
    Feb 25 at 16:05






  • 4





    I'd argue that it's not really a unit test once it starts depending on a real, rather than mocked, filesystem.

    – Toby Speight
    Feb 25 at 17:05














14












14








14








I need this for a unit test. There's a function that does lstat on the file path passed as its parameter. I have to trigger the code path where the lstat fails (because the code coverage has to reach 90%)



The test can run only under a single user, therefore I was wondering if there's a file in Ubuntu that always exists, but normal users have no read access to it, or to its folder. (So lstat would fail on it unless executed as root.)



A non-existent file is not a solution, because there's a separate code path for that, which I'm already triggering.



EDIT: Lack of read access to the file only is not enough. With that lstat can still be executed. I was able to trigger it (on my local machine, where I have root access), by creating a folder in /root, and a file in it. And setting permission 700 on the folder. So I'm searching for a file that is in a folder that is only accessible by root.










share|improve this question
















I need this for a unit test. There's a function that does lstat on the file path passed as its parameter. I have to trigger the code path where the lstat fails (because the code coverage has to reach 90%)



The test can run only under a single user, therefore I was wondering if there's a file in Ubuntu that always exists, but normal users have no read access to it, or to its folder. (So lstat would fail on it unless executed as root.)



A non-existent file is not a solution, because there's a separate code path for that, which I'm already triggering.



EDIT: Lack of read access to the file only is not enough. With that lstat can still be executed. I was able to trigger it (on my local machine, where I have root access), by creating a folder in /root, and a file in it. And setting permission 700 on the folder. So I'm searching for a file that is in a folder that is only accessible by root.







linux ubuntu permissions






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 26 at 10:47









psmears

44528




44528










asked Feb 25 at 11:50









Crouching KittenCrouching Kitten

323312




323312








  • 6





    IMHO /etc/shadow

    – Romeo Ninov
    Feb 25 at 11:52






  • 3





    You cannot assume the existence of any file, because your program may run in a chroot or separate namespace. If assuming that /proc is mounted is OK and init is nothing special, then /proc/1/fd/0 should do.

    – mosvy
    Feb 25 at 12:12








  • 1





    @mosvy Thanks that works on my local machine. Hmm then I'll try it on the QA and Staging pool too.

    – Crouching Kitten
    Feb 25 at 12:15






  • 2





    Why are you tying your test code to a particular flavor of OS when you could just create a throwaway file and remove your own read access to it?

    – Kilian Foth
    Feb 25 at 16:05






  • 4





    I'd argue that it's not really a unit test once it starts depending on a real, rather than mocked, filesystem.

    – Toby Speight
    Feb 25 at 17:05














  • 6





    IMHO /etc/shadow

    – Romeo Ninov
    Feb 25 at 11:52






  • 3





    You cannot assume the existence of any file, because your program may run in a chroot or separate namespace. If assuming that /proc is mounted is OK and init is nothing special, then /proc/1/fd/0 should do.

    – mosvy
    Feb 25 at 12:12








  • 1





    @mosvy Thanks that works on my local machine. Hmm then I'll try it on the QA and Staging pool too.

    – Crouching Kitten
    Feb 25 at 12:15






  • 2





    Why are you tying your test code to a particular flavor of OS when you could just create a throwaway file and remove your own read access to it?

    – Kilian Foth
    Feb 25 at 16:05






  • 4





    I'd argue that it's not really a unit test once it starts depending on a real, rather than mocked, filesystem.

    – Toby Speight
    Feb 25 at 17:05








6




6





IMHO /etc/shadow

– Romeo Ninov
Feb 25 at 11:52





IMHO /etc/shadow

– Romeo Ninov
Feb 25 at 11:52




3




3





You cannot assume the existence of any file, because your program may run in a chroot or separate namespace. If assuming that /proc is mounted is OK and init is nothing special, then /proc/1/fd/0 should do.

– mosvy
Feb 25 at 12:12







You cannot assume the existence of any file, because your program may run in a chroot or separate namespace. If assuming that /proc is mounted is OK and init is nothing special, then /proc/1/fd/0 should do.

– mosvy
Feb 25 at 12:12






1




1





@mosvy Thanks that works on my local machine. Hmm then I'll try it on the QA and Staging pool too.

– Crouching Kitten
Feb 25 at 12:15





@mosvy Thanks that works on my local machine. Hmm then I'll try it on the QA and Staging pool too.

– Crouching Kitten
Feb 25 at 12:15




2




2





Why are you tying your test code to a particular flavor of OS when you could just create a throwaway file and remove your own read access to it?

– Kilian Foth
Feb 25 at 16:05





Why are you tying your test code to a particular flavor of OS when you could just create a throwaway file and remove your own read access to it?

– Kilian Foth
Feb 25 at 16:05




4




4





I'd argue that it's not really a unit test once it starts depending on a real, rather than mocked, filesystem.

– Toby Speight
Feb 25 at 17:05





I'd argue that it's not really a unit test once it starts depending on a real, rather than mocked, filesystem.

– Toby Speight
Feb 25 at 17:05










3 Answers
3






active

oldest

votes


















21














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.






share|improve this answer





















  • 1





    Thanks! If /proc/1/fdinfo/0 works on Ubuntu 16.04 and 18.04, that's more than enough.

    – Crouching Kitten
    Feb 25 at 12:17






  • 1





    Using /proc/1/fdinfo/0 does not necessarily work in a container (e.g., a Docker container), and often unit tests are run in such containers in CI.

    – Philipp Wendler
    Feb 26 at 9:05











  • @PhilippWendler, I did mention the root pid namespace already. The OP is not asking about containers but about files guaranteed to be there in the filesystem layout of a Ubuntu system. As containers could contain any file and directory layout, that question could not be answerable there.

    – Stéphane Chazelas
    Feb 26 at 9:39



















12














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.






share|improve this answer


























  • @StephaneChazelas Great point! Updated.

    – filbranden
    Feb 25 at 15:22



















6














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.







share|improve this answer


























  • Thanks, I think my question is wrong. I can still lstat files without read access to them. Maybe the access to the folder has to be limited? (I modified the title)

    – Crouching Kitten
    Feb 25 at 11:59













  • Thanks. With find / -type d -perm 0400 -user root I have found the directory /proc/20/map_files/, if I refer to a made-up file name inside that folder, like /proc/20/map_files/asdasd, then it always fails. Does that folder always exist on Ubuntu?

    – Crouching Kitten
    Feb 25 at 12:12











  • @CrouchingKitten, the directories in /proc/1/ might be safer, since init always exists. But that's proc, not a regular filesystem, in case it matters.

    – ilkkachu
    Feb 25 at 12:17











  • Thanks I gave an upvote, but accepted the other answer, because he said it is guaranteed that /proc/1/fdinfo/0 works on modern Ubuntus.

    – Crouching Kitten
    Feb 25 at 12:21













  • -perm o-rwx is like -perm 0, bits are all off to start with. Here, you'd want ! -perm -1.

    – Stéphane Chazelas
    Feb 25 at 13:25











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f502857%2fis-there-a-file-that-always-exists-and-a-normal-user-cant-lstat-it%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









21














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.






share|improve this answer





















  • 1





    Thanks! If /proc/1/fdinfo/0 works on Ubuntu 16.04 and 18.04, that's more than enough.

    – Crouching Kitten
    Feb 25 at 12:17






  • 1





    Using /proc/1/fdinfo/0 does not necessarily work in a container (e.g., a Docker container), and often unit tests are run in such containers in CI.

    – Philipp Wendler
    Feb 26 at 9:05











  • @PhilippWendler, I did mention the root pid namespace already. The OP is not asking about containers but about files guaranteed to be there in the filesystem layout of a Ubuntu system. As containers could contain any file and directory layout, that question could not be answerable there.

    – Stéphane Chazelas
    Feb 26 at 9:39
















21














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.






share|improve this answer





















  • 1





    Thanks! If /proc/1/fdinfo/0 works on Ubuntu 16.04 and 18.04, that's more than enough.

    – Crouching Kitten
    Feb 25 at 12:17






  • 1





    Using /proc/1/fdinfo/0 does not necessarily work in a container (e.g., a Docker container), and often unit tests are run in such containers in CI.

    – Philipp Wendler
    Feb 26 at 9:05











  • @PhilippWendler, I did mention the root pid namespace already. The OP is not asking about containers but about files guaranteed to be there in the filesystem layout of a Ubuntu system. As containers could contain any file and directory layout, that question could not be answerable there.

    – Stéphane Chazelas
    Feb 26 at 9:39














21












21








21







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








edited Feb 26 at 7:15

























answered Feb 25 at 12:15









Stéphane ChazelasStéphane Chazelas

308k57582940




308k57582940








  • 1





    Thanks! If /proc/1/fdinfo/0 works on Ubuntu 16.04 and 18.04, that's more than enough.

    – Crouching Kitten
    Feb 25 at 12:17






  • 1





    Using /proc/1/fdinfo/0 does not necessarily work in a container (e.g., a Docker container), and often unit tests are run in such containers in CI.

    – Philipp Wendler
    Feb 26 at 9:05











  • @PhilippWendler, I did mention the root pid namespace already. The OP is not asking about containers but about files guaranteed to be there in the filesystem layout of a Ubuntu system. As containers could contain any file and directory layout, that question could not be answerable there.

    – Stéphane Chazelas
    Feb 26 at 9:39














  • 1





    Thanks! If /proc/1/fdinfo/0 works on Ubuntu 16.04 and 18.04, that's more than enough.

    – Crouching Kitten
    Feb 25 at 12:17






  • 1





    Using /proc/1/fdinfo/0 does not necessarily work in a container (e.g., a Docker container), and often unit tests are run in such containers in CI.

    – Philipp Wendler
    Feb 26 at 9:05











  • @PhilippWendler, I did mention the root pid namespace already. The OP is not asking about containers but about files guaranteed to be there in the filesystem layout of a Ubuntu system. As containers could contain any file and directory layout, that question could not be answerable there.

    – Stéphane Chazelas
    Feb 26 at 9:39








1




1





Thanks! If /proc/1/fdinfo/0 works on Ubuntu 16.04 and 18.04, that's more than enough.

– Crouching Kitten
Feb 25 at 12:17





Thanks! If /proc/1/fdinfo/0 works on Ubuntu 16.04 and 18.04, that's more than enough.

– Crouching Kitten
Feb 25 at 12:17




1




1





Using /proc/1/fdinfo/0 does not necessarily work in a container (e.g., a Docker container), and often unit tests are run in such containers in CI.

– Philipp Wendler
Feb 26 at 9:05





Using /proc/1/fdinfo/0 does not necessarily work in a container (e.g., a Docker container), and often unit tests are run in such containers in CI.

– Philipp Wendler
Feb 26 at 9:05













@PhilippWendler, I did mention the root pid namespace already. The OP is not asking about containers but about files guaranteed to be there in the filesystem layout of a Ubuntu system. As containers could contain any file and directory layout, that question could not be answerable there.

– Stéphane Chazelas
Feb 26 at 9:39





@PhilippWendler, I did mention the root pid namespace already. The OP is not asking about containers but about files guaranteed to be there in the filesystem layout of a Ubuntu system. As containers could contain any file and directory layout, that question could not be answerable there.

– Stéphane Chazelas
Feb 26 at 9:39













12














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.






share|improve this answer


























  • @StephaneChazelas Great point! Updated.

    – filbranden
    Feb 25 at 15:22
















12














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.






share|improve this answer


























  • @StephaneChazelas Great point! Updated.

    – filbranden
    Feb 25 at 15:22














12












12








12







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








edited Feb 25 at 15:21

























answered Feb 25 at 12:23









filbrandenfilbranden

10.3k21645




10.3k21645













  • @StephaneChazelas Great point! Updated.

    – filbranden
    Feb 25 at 15:22



















  • @StephaneChazelas Great point! Updated.

    – filbranden
    Feb 25 at 15:22

















@StephaneChazelas Great point! Updated.

– filbranden
Feb 25 at 15:22





@StephaneChazelas Great point! Updated.

– filbranden
Feb 25 at 15:22











6














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.







share|improve this answer


























  • Thanks, I think my question is wrong. I can still lstat files without read access to them. Maybe the access to the folder has to be limited? (I modified the title)

    – Crouching Kitten
    Feb 25 at 11:59













  • Thanks. With find / -type d -perm 0400 -user root I have found the directory /proc/20/map_files/, if I refer to a made-up file name inside that folder, like /proc/20/map_files/asdasd, then it always fails. Does that folder always exist on Ubuntu?

    – Crouching Kitten
    Feb 25 at 12:12











  • @CrouchingKitten, the directories in /proc/1/ might be safer, since init always exists. But that's proc, not a regular filesystem, in case it matters.

    – ilkkachu
    Feb 25 at 12:17











  • Thanks I gave an upvote, but accepted the other answer, because he said it is guaranteed that /proc/1/fdinfo/0 works on modern Ubuntus.

    – Crouching Kitten
    Feb 25 at 12:21













  • -perm o-rwx is like -perm 0, bits are all off to start with. Here, you'd want ! -perm -1.

    – Stéphane Chazelas
    Feb 25 at 13:25
















6














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.







share|improve this answer


























  • Thanks, I think my question is wrong. I can still lstat files without read access to them. Maybe the access to the folder has to be limited? (I modified the title)

    – Crouching Kitten
    Feb 25 at 11:59













  • Thanks. With find / -type d -perm 0400 -user root I have found the directory /proc/20/map_files/, if I refer to a made-up file name inside that folder, like /proc/20/map_files/asdasd, then it always fails. Does that folder always exist on Ubuntu?

    – Crouching Kitten
    Feb 25 at 12:12











  • @CrouchingKitten, the directories in /proc/1/ might be safer, since init always exists. But that's proc, not a regular filesystem, in case it matters.

    – ilkkachu
    Feb 25 at 12:17











  • Thanks I gave an upvote, but accepted the other answer, because he said it is guaranteed that /proc/1/fdinfo/0 works on modern Ubuntus.

    – Crouching Kitten
    Feb 25 at 12:21













  • -perm o-rwx is like -perm 0, bits are all off to start with. Here, you'd want ! -perm -1.

    – Stéphane Chazelas
    Feb 25 at 13:25














6












6








6







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.







share|improve this answer















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.








share|improve this answer














share|improve this answer



share|improve this answer








edited Feb 25 at 13:23









Stéphane Chazelas

308k57582940




308k57582940










answered Feb 25 at 11:56









heemaylheemayl

35.7k376105




35.7k376105













  • Thanks, I think my question is wrong. I can still lstat files without read access to them. Maybe the access to the folder has to be limited? (I modified the title)

    – Crouching Kitten
    Feb 25 at 11:59













  • Thanks. With find / -type d -perm 0400 -user root I have found the directory /proc/20/map_files/, if I refer to a made-up file name inside that folder, like /proc/20/map_files/asdasd, then it always fails. Does that folder always exist on Ubuntu?

    – Crouching Kitten
    Feb 25 at 12:12











  • @CrouchingKitten, the directories in /proc/1/ might be safer, since init always exists. But that's proc, not a regular filesystem, in case it matters.

    – ilkkachu
    Feb 25 at 12:17











  • Thanks I gave an upvote, but accepted the other answer, because he said it is guaranteed that /proc/1/fdinfo/0 works on modern Ubuntus.

    – Crouching Kitten
    Feb 25 at 12:21













  • -perm o-rwx is like -perm 0, bits are all off to start with. Here, you'd want ! -perm -1.

    – Stéphane Chazelas
    Feb 25 at 13:25



















  • Thanks, I think my question is wrong. I can still lstat files without read access to them. Maybe the access to the folder has to be limited? (I modified the title)

    – Crouching Kitten
    Feb 25 at 11:59













  • Thanks. With find / -type d -perm 0400 -user root I have found the directory /proc/20/map_files/, if I refer to a made-up file name inside that folder, like /proc/20/map_files/asdasd, then it always fails. Does that folder always exist on Ubuntu?

    – Crouching Kitten
    Feb 25 at 12:12











  • @CrouchingKitten, the directories in /proc/1/ might be safer, since init always exists. But that's proc, not a regular filesystem, in case it matters.

    – ilkkachu
    Feb 25 at 12:17











  • Thanks I gave an upvote, but accepted the other answer, because he said it is guaranteed that /proc/1/fdinfo/0 works on modern Ubuntus.

    – Crouching Kitten
    Feb 25 at 12:21













  • -perm o-rwx is like -perm 0, bits are all off to start with. Here, you'd want ! -perm -1.

    – Stéphane Chazelas
    Feb 25 at 13:25

















Thanks, I think my question is wrong. I can still lstat files without read access to them. Maybe the access to the folder has to be limited? (I modified the title)

– Crouching Kitten
Feb 25 at 11:59







Thanks, I think my question is wrong. I can still lstat files without read access to them. Maybe the access to the folder has to be limited? (I modified the title)

– Crouching Kitten
Feb 25 at 11:59















Thanks. With find / -type d -perm 0400 -user root I have found the directory /proc/20/map_files/, if I refer to a made-up file name inside that folder, like /proc/20/map_files/asdasd, then it always fails. Does that folder always exist on Ubuntu?

– Crouching Kitten
Feb 25 at 12:12





Thanks. With find / -type d -perm 0400 -user root I have found the directory /proc/20/map_files/, if I refer to a made-up file name inside that folder, like /proc/20/map_files/asdasd, then it always fails. Does that folder always exist on Ubuntu?

– Crouching Kitten
Feb 25 at 12:12













@CrouchingKitten, the directories in /proc/1/ might be safer, since init always exists. But that's proc, not a regular filesystem, in case it matters.

– ilkkachu
Feb 25 at 12:17





@CrouchingKitten, the directories in /proc/1/ might be safer, since init always exists. But that's proc, not a regular filesystem, in case it matters.

– ilkkachu
Feb 25 at 12:17













Thanks I gave an upvote, but accepted the other answer, because he said it is guaranteed that /proc/1/fdinfo/0 works on modern Ubuntus.

– Crouching Kitten
Feb 25 at 12:21







Thanks I gave an upvote, but accepted the other answer, because he said it is guaranteed that /proc/1/fdinfo/0 works on modern Ubuntus.

– Crouching Kitten
Feb 25 at 12:21















-perm o-rwx is like -perm 0, bits are all off to start with. Here, you'd want ! -perm -1.

– Stéphane Chazelas
Feb 25 at 13:25





-perm o-rwx is like -perm 0, bits are all off to start with. Here, you'd want ! -perm -1.

– Stéphane Chazelas
Feb 25 at 13:25


















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f502857%2fis-there-a-file-that-always-exists-and-a-normal-user-cant-lstat-it%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to change which sound is reproduced for terminal bell?

Can I use Tabulator js library in my java Spring + Thymeleaf project?

Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents