sudo 對 ROWHAMMER 攻擊的 mitigation

看到「Rowhammer Resistant Coding in Sudo (github.com/sudo-project)」這邊的討論,提到了 sudo 專案 (變成 root 那個 sudo 軟體) 怎麼緩解 ROWHAMMER 攻擊的實作,原連結是去年九月時 GitHub 上的 commit:「Try to make sudo less vulnerable to ROWHAMMER attacks.」。

從 commit 裡面可以看到這個:

- #define AUTH_SUCCESS		0
- #define AUTH_FAILURE		1
- #define AUTH_INTR		2
- #define AUTH_ERROR		3
- #define AUTH_NONINTERACTIVE	4
+ #define AUTH_SUCCESS		0x52a2925	/* 0101001010100010100100100101 */
+ #define AUTH_FAILURE		0xad5d6da	/* 1010110101011101011011011010 */
+ #define AUTH_INTR		0x69d61fc8	/* 1101001110101100001111111001000 */
+ #define AUTH_ERROR		0x1629e037	/* 0010110001010011110000000110111 */
+ #define AUTH_NONINTERACTIVE	0x1fc8d3ac	/* 11111110010001101001110101100 */

可以看到想法上是讓要攻擊時需要改變的 bit 數量大幅增加?尤其是對 AUTH_SUCCESShamming distance

另外這段也是類似的設計:

+ /* Allowed by policy (rowhammer resistent). */
+ #undef ALLOW
+ #define ALLOW	 0x52a2925	/* 0101001010100010100100100101 */
+ 
+ /* Denied by policy (rowhammer resistent). */
+ #undef DENY
+ #define DENY	 0xad5d6da	/* 1010110101011101011011011010 */

這邊 ALLOWDENY 這邊也是把 hamming distance 設計到最大,兩個 XOR 後剛好是 0xffffffff

會不會變成安全相關軟體實作上的 practice?

Content Defined Chunking (CDC)

前幾個禮拜在 Hacker News Daily 上看到「CDC File Transfer (github.com/google)」這則,連結是指到 GoogleGitHub 專案上,裡面實做了 FastCDC 演算法,另外說明他們為什麼要解這個問題以及對應的成果:「google/cdc-file-transfer」。

Google 的人看起來像是是在 CI/CD 階段遇到頻寬上的問題 (從「The builds are 40-45 GB large.」這邊猜),用 scprsync 看起來都不能解,所以他們自己刻了 FastCDC 演算法來解。

但我對 Content Defined Chunking (CDC) 不熟,所以先查一下 CDC 是什麼東西,就查到 restic 這篇講得很清楚:「Foundation - Introducing Content Defined Chunking (CDC)」。

要計算 delta 很直覺的作法就是要切 chunk,而接著的直覺就是固定大小的 chunk 切開,像是這樣每 16 bytes 切一個 chunk:

0123456789abcdef 0123456789abcdef 0123456789abcdef 0123456789abcdef

如果其中一個地方有變化,但其他沒變化的話就可以透過 cryptographic hash function (像是 SHA-256) 確認 chunk 內容一樣,進而省下很多傳輸的頻寬:

0123456789abcdef 0123456789ABCDEF 0123456789abcdef 0123456789abcdef

但可以馬上看出來這個方法的大缺點是只能處理 replacement,很難處理 insert & delete 的部份,舉例來說,如果變更是在開頭的地方加上 ABC,就會造成 chunk 會完全不一樣,而導致全部都要再傳一次:

ABC0123456789abc def0123456789abc def0123456789abc def0123456789abc def

這邊其實是個經典的演算法問題:想要找出兩個 string 的差異 (把舊的內容當作一個 string,新的內容也當作一個 string)。

這個問題算是 Edit distance 類型的題目,但你會發現解 Edit distance 的演算法會需要先傳輸完整個 string 才能開始跑演算法,這就本末倒置了。

而另外一個想法是,放棄固定的 chunk 大小,改用其他方式決定 chunk 的邊界要切在哪裡。而 CDC 就是利用一段 sliding window + hash 來找出切割的點。

文章裡面提到的 sliding window 是 64 bytes,這邊就可以算出對應的 HASH(b0, b1, ..., b63),然後往右滑動變成 HASH(b1, b2, ..., b64),再來是 HASH(b2, b3, ..., b65),一直往右滑動計算。

接下來 restic 會看 hash 值,如果最低的 21 bits 都是 0 就切開,所以 chunk 大小的期望值應該是 2MB?(這邊不確定,好像不能直接用 2^21 算,應該用積分之類的方法...)

For each fingerprint, restic then tests if the lowest 21 bits are zero. If this is the case, restic found a new chunk boundary.

而這個演算法可以適應新增與刪除的操作,不會造成從新增或刪除後的資料都要重傳,只有自己這個 chunk 需要重傳 (可能前或後的 chunk 也會要)。

然後挑一下 hash function 的特性,就可以讓計算的速度也很快。這邊提到了 hash function 可以用 Rolling hash,可以很快的從 HASH(b0, b1, ..., b63) 算出 HASH(b1, b2, ..., b64),而不需要全部重算。

有了 chunk 後,再用 cryptographic hash function 比較 chunk 的內容是否一樣,這樣就可以大幅降低傳輸所需要的頻寬了。

GrabFood 用定位資料修正餐廳的資訊

Grab 的「How we harnessed the wisdom of crowds to improve restaurant location accuracy」這篇是他們的 data team 整理出來,如何使用既有的資料快速的修正餐廳資訊。裡面提到的方法不需要用到 machine learning,光是一些簡單的統計算法就可以快速修正現有的架構。

這些資訊其實是透過司機用的 driver app 蒐集來的,在 driver app 上有大量的資訊傳回伺服器 (像是定時回報的 GPS 位置,以及取餐狀態),而這些司機因為地緣關係,腦袋裡的資訊比地圖會準不少:

One of the biggest advantages we have is the huge driver-partner fleet we have on the ground in cities across Southeast Asia. They know the roads and cities like the back of their hand, and they are resourceful. As a result, they are often able to find the restaurants and complete orders even if the location was registered incorrectly.

所以透過這些資訊他們就可以反過來改善地圖資料,像是透過司機按下「取餐」的按鈕的地點與待的時間,就可以估算餐聽可能的位置,然後拿這個資訊比對地圖上的資料,就很容易發現搬家但是地圖上沒更新的情況:

Fraction of the orders where the pick-up location was not “at” the restaurant: This fraction indicates the number of orders with a pick-up location not near the registered restaurant location (with near being defined both spatially and temporally as above). A higher value indicates a higher likelihood of the restaurant not being in the registered location subject to order volume

Median distance between registered and estimated locations: This factor is used to rank restaurants by a notion of “importance”. A restaurant which is just outside the fixed radius from above can be addressed after another restaurant which is a kilometer away.

另外也有不少其他的改善 (像是必須在離餐聽某個距離內才能點「取餐」,這個「距離」會因為餐聽可能在室內商場而需要的調整),整個成果就會反應在訂單的取消率大幅下降:

整體看起來是系統產生清單後讓人工後續處理 (像是打電話去店家問?),但這個方式所提供的清單準確度應該很高 (因為司機不會沒事跟自己時間過不去,跑到奇怪地方按下取餐),用這些資料跑簡單的演算法就能夠快速修正不少問題...

依照交通時間,評估各種「地點」的服務...

Oalley 這個服務利用「交通時間」來評估地點,最簡單的應用像是給一個地點與時間,畫出範圍:

或是給多個點以及時間來評估地點:

不過後面是用 OpenStreetMap 的資料,我丟了幾個中文測試好像都找不到,用英文倒是可以...