2013-04-20 132 views
2

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

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,文件描述符存储在类型为uint64_t的fh中。由于这个程序执行的方式,我知道两个链接文件的文件描述符号码总是相隔1。至少这是我的工作假设,我试图用此代码验证。

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

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

回答

2

如果您的代码变得不可移植并且被绑定到在某种现代版本的Linux上运行,那么您可以使用/proc/<pid>/fd/<fd>。然而,我建议不要给fd加'0'作为获得表示数字的字符串的方法,因为它使用假设fd < 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/...路径访问它。但是,如果您使用,则会得到原始路径名(附加'(删除)'文本)。

如果您的文件是/tmp/a.txt并且被删除,/proc/...路径上的readlink返回/tmp/a.txt (deleted)。如果此路径存在,您将能够访问它,而您想访问另一个文件(/tmp/a.txt)。攻击者可能能够在/tmp/a.txt (deleted)文件中提供敌对内容。另一方面,如果您只是通过/proc/...路径访问文件,即使路径声称是其他链接,您也将访问正确的(未链接但仍活着)文件。