使用带有readlink的文件描述符()

时间:2013-04-20 06:52:41

标签: c filenames file-descriptor

我有一种情况需要获取文件名,以便我可以调用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。至少这是我的工作假设,我试图用这段代码验证。

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

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

1 个答案:

答案 0 :(得分:2)

如果您的代码变得不可移植并且与在某种现代版本的Linux上运行相关联,那么您可以使用/proc/<pid>/fd/<fd>。但是,我建议不要在fd中添加'0'作为获取表示数字的字符串的方法,因为它使用假设fd&lt; 10。

但是,如果您只能选择文件名而不是依赖/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并且该文件已被删除,则readlink路径上的/proc/...会返回/tmp/a.txt (deleted)。如果此路径存在,您将能够访问它!,而您想要访问其他文件(/tmp/a.txt)。攻击者可能能够在/tmp/a.txt (deleted)文件中提供恶意内容。

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