[英]Can short-circuit evaluation trigger a race condition?
我喜歡打高爾夫球。 鑒於CVE-2016-5195 ,我想知道我的任何“ golf”代碼是否都可以觸發競爭條件。
假設我們有兩個函數,兩個函數都返回一個布爾值,並且我們正在初始化一個名為result
的布爾變量:
result = foo() || bar();
在理想的世界中,我們有兩種情況:
foo
返回true
。 不要打電話bar
。 result
等於true
。 [短路情況] foo
返回false
。 請致電bar()
result
等於bar
返回的值。 我的問題是:是否會有一段時間違反短路評估,並且盡管foo
返回true
foo
調用bar
,或更糟糕的是,可能是由於多線程而在foo
被調用之前先調用bar
嗎? 如果是這樣,您是否可以提供一段代碼來觸發這種行為?
您的答案可能是關於使用該語法有效的任何一種或多種語言的,盡管我認為某些語言對這種語言的要求會比其他語言更為嚴格。
當一系列操作的結果取決於執行這些操作的順序時,就會發生競爭條件。
&&
和||
C ++中的運算符保證從左到右求值,並且如果第一個運算符為false / true則不對第二個運算符進行求值。 由於操作順序是有保證的,因此foo
操作和bar
操作之間沒有競爭條件。 但是,每個操作之間仍然存在競爭條件。
違反上述保證的代碼不是C ++代碼,同樣,符合要求的C ++編譯器也永遠不會發出違反那些保證的代碼。
您所指的情況不是競爭條件。 讓我們再次回到您的問題:
是否會有一段時間違反短路評估,盡管foo返回true仍會調用bar,或者更糟糕的是,可能由於多線程而在調用foo之前先調用bar嗎?
我猜正確的問題是:
將永遠是一個有酒吧時被調用后調用函數foo使用假的結果的時間,但同時它被稱為foo將返回true,如果將被再次叫什么名字?
好的,讓我們用潛在的race condition
狀態編寫一些代碼。
#define BUFFER_SIZE 0x1000
char globalBuffer[BUFFER_SIZE];
bool foo() { // have user an access to the path_to_file file?
return access(path_to_file, 0666) != 0; // path_to_file declared somewhere
}
bool bar() {
FILE *file = fopen(path_to_file, "r");
if (file == NULL) return false;
char *ptr = gfets(globalBuffer, BUFFER_SIZE, file);
if (ptr == NULL) return false;
return true;
}
...
result = foo() || bar(); // if foo is false, then user have an access
printf("%s", globalBuffer);
假設我們可以控制path_to_file。
如果我們像這樣做一個無限循環,就會出現競爭條件
#!/bin/bash
while :
do
ln -s /path/to/good/access/file /path/to/file
rm -f /path/to/file
ln -s /etc/shadow /path/to/file
done
經過一些嘗試,如果您的應用程序具有suid位-我將讀取/ etc / shadow的內容
但是,讓我們回到您的問題:
不行不行 如果foo
返回true,則不會調用bar
。 即使您來自其他線程,如果您有多線程。 每個線程都有自己的寄存器和堆棧。 因此,在同一個表達式中調用兩個函數的情況下,您應該相信c ++標准。 但這並不意味着您的代碼是安全的。 種族狀況是100種可能出現的問題之一。
請注意,C ++支持運算符重載,但短路僅是內置運算符(c ++ 17之前)的功能,而不是用戶提供的重載。
也就是說,在所有當前版本的C ++中,除非您同時知道這兩種類型並且知道沒有自由函數運算符,否則不能假定會發生短路。 正在陰影中。
有關p0145的信息 ,請參見c ++ 17中的變化。
(粗體是加法,斜體去除)
更改第5/2段,如下所示:[注意:運算符可以重載,即在應用於類類型(條款9)或枚舉類型(7.2)的表達式時具有特定含義。 重載運算符的使用將轉換為函數調用,如13.5中所述。 重載的運算符遵循第5章中指定的語法和評估順序規則,但操作數類型*,* 和值類別以及評估順序的要求已由函數調用規則取代。 對於重載的運算符(13.5),不能保證運算符之間的關系(例如++ a表示a + = 1),對於布爾類型的操作數也不保證。 —尾注]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.