2013-04-20 174 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/...路徑訪問文件,即使路徑聲稱是其他鏈接,您也將訪問正確的(未鏈接但仍活着)文件。