【问题标题】:Using File Descriptors with readlink()将文件描述符与 readlink() 一起使用
【发布时间】:2013-04-20 06:52:41
【问题描述】:

我有一种情况需要获取文件名,以便调用 readlink() 函数。我所拥有的只是一个整数,它最初通过 open() 命令存储为文件描述符。问题是,我无权访问执行 open() 命令的函数(如果我这样做了,那么我就不会发布这个)。 open() 的返回值存储在我确实可以访问的结构中。

char buf[PATH_MAX];

char tempFD[2]; //file descriptor number of the temporary file created
tempFD[0] = fi->fh + '0';
tempFD[1] = '\0';

char parentFD[2]; //file descriptor number of the original file
parentFD[0] = (fi->fh - 1) + '0';
parentFD[1] = '\0';

if (readlink(tempFD, buf, sizeof(buf)) < 0) {
    log_msg("\treadlink() error\n");
    perror("readlink() error");
} else 
    log_msg("readlink() returned '%s' for '%s'\n", buf, tempFD);

这是 FUSE 文件系统的一部分。该结构称为fi,文件描述符存储在fh中,其类型为uint64_t。由于该程序的执行方式,我知道两个链接文件的文件描述符编号始终相隔 1。至少这是我的工作假设,我正在尝试使用此代码进行验证。

这可以编译,但是当我运行它时,我的日志文件每次都显示读取链接错误。我的文件描述符中存储了正确的整数值,但它不起作用。

有谁知道我如何从这些整数值中获取文件名?谢谢!

【问题讨论】:

    标签: c filenames file-descriptor


    【解决方案1】:

    如果您的代码变得不可移植并且被绑定到在较现代的 Linux 版本上运行是可以接受的,那么您可以使用/proc/&lt;pid&gt;/fd/&lt;fd&gt;。但是,我建议不要在 fd 中添加 '0' 作为获取表示数字的字符串的方法,因为它使用 fd

    但是,如果您能够只获取文件名而不是依赖/proc,那将是最好的。至少,您可以使用链接器标志将调用库函数替换为包装函数。用法示例为gcc program.c -Wl,-wrap,theFunctionToBeOverriden -o program,所有对库函数的调用都将链接到__wrap_theFunctionToBeOverriden;原始函数可在名称 __real_theFunctionToBeOverriden 下访问。有关详细信息,请参阅此答案https://stackoverflow.com/a/617606/111160

    但是,回到不涉及链接重新路由的答案:您可以这样做

     char fd_path[100];
     snprintf("/proc/%d/fd/%d", sizeof(fd_path), getpid(), fi->fh);
    

    您现在应该使用这个/proc/... 路径(它是一个软链接),而不是使用它链接到的路径。

    您可以调用readlink 来查找文件系统中的实际路径。但是,这样做会引入一个安全漏洞,我建议不要使用readlink 返回的路径。

    当描述符指向的文件被删除、取消链接时,你仍然可以通过/proc/...路径访问它。但是,当您在上面readlink 时,您会得到原始路径名(附加一个“(已删除)”文本)。

    如果您的文件是 /tmp/a.txt 并且它被删除,/proc/... 路径上的 readlink 将返回 /tmp/a.txt (deleted)。如果此路径存在,您将能够访问它!,而您想访问不同的文件 (/tmp/a.txt)。攻击者可能能够在/tmp/a.txt (deleted) 文件中提供恶意内容。

    另一方面,如果您只是通过/proc/... 路径访问该文件,您将访问正确的(未链接但仍然有效)文件,即使该路径声称是指向其他内容的链接。

    【讨论】:

    • 可以用/proc/&lt;pid&gt;/fd代替/proc/self/fd
    猜你喜欢
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    相关资源
    最近更新 更多