是否有一个文件始终存在而“普通”用户无法对其进行 lstat?

Cro*_*ten 13 linux ubuntu permissions

我需要这个进行单元测试。有一个函数对作为其参数传递的文件路径执行lstat。我必须触发lstat失败的代码路径(因为代码覆盖率必须达到 90%)

该测试只能在单个用户下运行,因此我想知道 Ubuntu 中是否有一个始终存在的文件,但普通用户对其或其文件夹没有读取权限。(所以lstat除非以 root 身份执行,否则会失败。)

不存在的文件不是解决方案,因为有一个单独的代码路径,我已经触发了。

编辑:仅缺乏对文件的读取权限是不够的。这样lstat仍然可以执行。我能够通过在 /root 中创建一个文件夹并在其中创建一个文件来触发它(在我具有 root 访问权限的本地计算机上)。并在文件夹上设置权限 700。因此,我正在搜索位于只能由 root 访问的文件夹中的文件。

Sté*_*las 21

在现代 Linux 系统上,您应该能够使用/proc/1/fdinfo/0(id 1 进程的文件描述符 1(stdout)的信息(init在应该作为 运行的根 pid 命名空间中root))。

您可以找到一个列表(作为普通用户):

sudo find /etc /dev /sys /proc -type f -print0 |
  perl -l -0ne 'print unless lstat'
Run Code Online (Sandbox Code Playgroud)

-type f如果您不想限制为常规文件,请删除)。

/var/cache/ldconfig/aux-cache如果您只需要考虑 Ubuntu 系统,那么它是另一个潜在的候选者。它应该可以在大多数 GNU 系统上运行,因为/var/cache/ldconfig它只能通过ldconfigGNU libc 附带的命令创建为 root 的 read+write+searchable 。


fil*_*den 12

查看lstat(2)手册页,您可以获得有关可能使其失败并出现 ENOENT 以外的错误(文件不存在)的情况的一些灵感。

最明显的是:

EACCES 搜索权限被拒绝对路径前缀的目录之一的路径

所以你需要一个无法搜索的目录。

是的,您可以查找系统中已有的一个(也许/var/lib/private它存在?)但您也可以自己创建一个,相当于:

$ mkdir myprivatedir
$ touch myprivatedir/myunreachablefile
$ chmod 0 myprivatedir
$ ls -l myprivatedir/myunreachablefile
Run Code Online (Sandbox Code Playgroud)

lstat(2) 操作将在此处失败并显示 EACCES。(从目录中删除所有权限确保了这一点。也许你甚至不需要那么多,chmod -x删除执行权限就足够了,因为访问目录下的文件需要执行权限。)

还有另一种创造性的方法可以使 lstat(2) 失败,请查看其手册页:

ENOTDIR 路径前缀的组成部分路径不是目录。

因此,尝试访问诸如/etc/passwd/nonexistent应该触发此错误的文件,这又与 ENOENT(“没有此类文件或目录”)不同,并且可能适合您的需要。

另一种是:

ENAMETOOLONG 路径太长。

但是你可能需要一个很长的名字(我相信 4,096 字节是典型的限制,但你的系统/文件系统可能有一个更长的。)

最后,很难说这些中的任何一个是否真的对您有用。你说你想要一些不会触发“文件不存在”场景的东西。虽然通常这意味着 ENOENT 错误,但实际上许多更高级别的检查只会将 lstat(2) 中的任何错误解释为“不存在”。例如,test -e[ -e ...]来自 shell的等效项可能只是将上述所有内容解释为“不存在”,特别是因为它没有返回不同错误消息的好方法,并且不返回错误将意味着该文件存在,事实肯定不是这样。


hee*_*ayl 6

find自己可以。

使用/etc-- 配置文件目录作为起点:

sudo find /etc -type f -perm 0400 -user root
Run Code Online (Sandbox Code Playgroud)

在我的系统上,这不会返回任何内容。

您可以减少限制并允许组root(只有用户root应该是组的成员root),并注意以下权限440

sudo find /etc -perm 0440 -user root -group root
Run Code Online (Sandbox Code Playgroud)

在我的系统上,这将返回:

/etc/sudoers.d/README
/etc/sudoers
Run Code Online (Sandbox Code Playgroud)

编辑:

根据您的编辑,您正在寻找一个目录,该目录没有足够的权限让调用用户阻止目录列表:

sudo find / -perm o-rwx -type d -user root -group root 
Run Code Online (Sandbox Code Playgroud)

在这里,我正在寻找-type d缺少其他人 ( o-rwx)的读写执行权限位且归root:root.

从技术上讲,仅缺少 execute ( x) 位将阻止目录lstat(2)上的目录列表 ( )。

在我在/run/systemd/inaccessible/基于 Systemd init 的系统上找到的输出中。

关于/proc, /sys, 中的文件/dev

  • 这些文件系统是虚拟文件系统,即它们驻留在内存上,而不是磁盘上

  • 如果您打算依赖/proc,请使用/proc/1/ie 依赖 PID 1 下的某些内容,而不是任何较晚的 PID 具有可靠性/一致性,因为不保证较晚的 PID(进程)存在。