首頁(yè)>資訊 >
微軟也栽了,“千年蟲”啥時(shí)候是個(gè)頭 2022-01-13 17:08:30  來(lái)源:36氪

新年伊始,微軟 Exchange Server 2016 與 2019 中出現(xiàn)日期檢查錯(cuò)誤,導(dǎo)致服務(wù)器無(wú)法正確識(shí)別 2022 年這一時(shí)間標(biāo)記。因此也有人稱其為 Y2K22 bug,即千年蟲 2022 版。

據(jù)悉,微軟的郵件程序會(huì)將日期與時(shí)間存儲(chǔ)為 signed 整數(shù)(帶符號(hào)的整數(shù)),最大值為 2147483647,即 2^31 - 1。而微軟使用更新版本的前兩位數(shù)字表示其發(fā)布年份,所以只要時(shí)間在 2021 年或更早,那就一切 OK。然而,就在微軟于新年前夜發(fā)布 2201010001 版本時(shí),本地服務(wù)器卻由于無(wú)法正確解析日期而發(fā)生崩潰,導(dǎo)致遞送消息卡在傳輸隊(duì)列中動(dòng)彈不得。

世界各地的管理員瘋狂排查故障,錯(cuò)過(guò)了與親朋好友一同迎接新年的寶貴時(shí)光?!拔④浀降自诟闶裁垂??馬上要過(guò)年了,要不是論壇上說(shuō)大家普遍遇到了問(wèn)題,我們就要重新跑回去上班了?!币晃还芾韱T在 Reddit 線程中寫道。

微軟在次日發(fā)布了修復(fù)方案:自動(dòng) PowerShell 腳本和腳本也無(wú)法運(yùn)行時(shí)適用的手動(dòng)解決方案。無(wú)論如何,管理員都需要在受到影響的每臺(tái)本地 Exchange 2016 與 2019 服務(wù)器上分別執(zhí)行修復(fù)操作。好在自動(dòng)化腳本可以在多臺(tái)服務(wù)器上并行運(yùn)行。微軟公司強(qiáng)調(diào),自動(dòng)化腳本“可能需要一段時(shí)間才能運(yùn)行完成”,并呼吁管理員們耐心等待。

日期與時(shí)間檢查是在 Exchange 檢查 FIP-FS 版本的過(guò)程中執(zhí)行的,F(xiàn)IP-FS 是一種掃描引擎、屬于 Exchange 反惡意軟件保護(hù)機(jī)制中的組成部分。一旦 FIP-FS 的版本是以數(shù)字 22 開頭,則檢查將無(wú)法完成、投遞中的郵件也會(huì)被突然叫停。微軟發(fā)布的修復(fù)程序會(huì)停止 Microsoft 篩選管理與 Microsoft Exchange 傳輸服務(wù)、刪除現(xiàn)有反病毒引擎文件,并安裝和啟動(dòng)經(jīng)過(guò)修復(fù)的新反病毒引擎。

目前,大部分受到波及的組織已經(jīng)恢復(fù)正常,但還不清楚這項(xiàng) bug 已經(jīng)存在了多久,不過(guò)從受影響的版本判斷,很可能源自 Exchange Server 2016 的開發(fā)階段。

一直在重蹈覆轍

從根本上說(shuō),千年蟲是一種程序處理日期上的 bug,這并不是嚴(yán)重的技術(shù)問(wèn)題,但卻是企業(yè)們一直在犯的錯(cuò)誤。

2019 年 11 月,部分惠普 SSD 固態(tài)硬盤在運(yùn)行 32768 小時(shí)后自動(dòng)停止工作,盤內(nèi)存儲(chǔ)內(nèi)容全部消失且無(wú)法恢復(fù)。特定系統(tǒng)中的所有驅(qū)動(dòng)器可能都預(yù)裝有相同批次的固件、有著同樣的 bug 隱患,一旦同時(shí)發(fā)生故障,即使是 RAID 系統(tǒng)也承受不了這種“集體罷工”式的極端狀況。

惠普并沒(méi)有做出具體解釋,而是直接發(fā)布了固件修復(fù)升級(jí)。但從現(xiàn)象來(lái)看,問(wèn)題應(yīng)該是與代碼中的 16 位值有關(guān)。這意味著此系統(tǒng)可負(fù)載的最大負(fù)整數(shù)是 32768,最大正整數(shù)則是 32767。

數(shù)字溢出問(wèn)題是最為常見的編程錯(cuò)誤之一,一旦值達(dá)到極限條件而且未經(jīng)溢出或下溢檢查的校正,那任何代碼都有可能出現(xiàn)問(wèn)題。因此,很多開發(fā)者喜歡用超級(jí)大的整數(shù)進(jìn)行標(biāo)定;只要數(shù)字夠大就不怕意外溢出。

不過(guò),這招并非百試百靈。微控制器中只能使用 8 位或者 16 位整數(shù)??紤]到這些值往往與外圍控制器相關(guān)聯(lián),所以必須要為其設(shè)置適當(dāng)?shù)姆秶拗?,確保開發(fā)者和代碼審查者能夠準(zhǔn)確掌握這些重要數(shù)值。

另一方面,這類超限狀況常常引發(fā)難以發(fā)現(xiàn)的 bug?;萜?SSD 事件中,驅(qū)動(dòng)器要運(yùn)行幾年才能達(dá)到極限時(shí)長(zhǎng),所以這種在罕見條件下才會(huì)觸發(fā)的錯(cuò)誤確實(shí)不易被察覺。如果這塊 SSD 恰好服務(wù)于某臺(tái)自動(dòng)駕駛汽車,那么在它停止工作的瞬間,車輛很有可能引發(fā)嚴(yán)重的交通事故。

除了惠普 SSD 事件,阿麗亞娜 -5 運(yùn)載火箭首次測(cè)試發(fā)射失敗的原因也是這樣的一個(gè)“小”失誤。1996 年 6 月 4 日,阿麗亞娜 -5 運(yùn)載火箭首次測(cè)試發(fā)射,火箭在發(fā)射后 37 秒被迫自行引爆,40 秒后解體。這個(gè)價(jià)值 5 億美元的運(yùn)載系統(tǒng)瞬間灰飛煙滅。

阿麗亞娜 5 號(hào) 某段控制程序直接復(fù)用了阿麗亞娜 4 號(hào)火箭的代碼,其中一個(gè)需要接收 64 位數(shù)據(jù)的變量為了節(jié)省存儲(chǔ)空間而使用了 16 位字節(jié),這使更快的阿麗亞娜 5 號(hào)在控制過(guò)程中產(chǎn)生了整數(shù)溢出,導(dǎo)致導(dǎo)航系統(tǒng)對(duì)火箭控制失效,程序進(jìn)入異常處理模塊,引爆自毀。該失敗成為歷史上最臭名昭著和最昂貴的軟件 bug 之一。

曾讓全世界感到恐懼

“千年蟲”問(wèn)題的根源始于 60 年代。當(dāng)時(shí)計(jì)算機(jī)存儲(chǔ)器的成本很高,如果用四位數(shù)字表示年份就要多占用存儲(chǔ)器空間,使成本增加。因此為了節(jié)省存儲(chǔ)空間,計(jì)算機(jī)系統(tǒng)的編程人員采用兩位數(shù)字表示年份。

雖然提高了計(jì)算機(jī)的運(yùn)行效率,但也帶來(lái)新的隱患。比如當(dāng)日期從 1999 年滾動(dòng)至 2000 年時(shí),99 到 00 的變化會(huì)引發(fā)哪些后果?有些人擔(dān)心計(jì)算機(jī)會(huì)不知道如何理解這樣一個(gè)時(shí)間空值,導(dǎo)致日期無(wú)效、進(jìn)而引發(fā)全球性計(jì)算設(shè)施故障。

為了使“1999 年 12 月 31 日”安全過(guò)度到“2000 年 1 月 1 日”,數(shù)據(jù)顯示,當(dāng)時(shí)全球大概投入了 3000 億~6000 億美元來(lái)解決千年蟲問(wèn)題。雖然效果不錯(cuò),但還是出現(xiàn)了一些問(wèn)題,甚至笑話。

對(duì)于千年蟲問(wèn)題,美國(guó)的態(tài)度和行動(dòng)特別積極。當(dāng)時(shí),美國(guó)整個(gè)國(guó)家至少投入的 1000 億美元中,約 90 億美元花在聯(lián)邦政府身上。五角大樓的情報(bào)和國(guó)防系統(tǒng)成為資金的主要目的地(總額約 35 億美元)。但是,雖然開展了為期數(shù)月的昂貴計(jì)算機(jī)修復(fù)與硬件更新努力,政府在 2000 年的頭三天內(nèi)仍然遭遇到嚴(yán)重的間諜衛(wèi)星運(yùn)行故障。直到經(jīng)歷了重啟和再次運(yùn)行,衛(wèi)星才終于能夠正常發(fā)回可以識(shí)別的信息內(nèi)容。

三天時(shí)間聽起來(lái)不長(zhǎng),但五角大樓的一位官員仍將此次事件劃入“重大”類別。不過(guò)略顯諷刺的是,引發(fā)故障的并不是千年蟲、而是用來(lái)解決該 bug 的軟件補(bǔ)丁。

此外,美國(guó)海軍天文臺(tái)也因千年蟲影響暫時(shí)失控。美國(guó)海軍天文臺(tái)只有一項(xiàng)工作:校準(zhǔn)時(shí)間。該機(jī)構(gòu)成立于 1830 年,主要負(fù)責(zé)美國(guó)各類航海儀器,并在后續(xù)的發(fā)展中逐漸成為美國(guó)的官方計(jì)時(shí)機(jī)構(gòu)。正是由于如此重要的地位,才讓海軍天文臺(tái)在千禧年第一天宣布日期為“19100 年 1 月 1 日”顯得格外尷尬,雖然問(wèn)題在上報(bào)不到一小時(shí)后就被解決。

1999 年 12 月 29 日,位于華盛頓特區(qū)的美國(guó)海軍天文臺(tái)內(nèi)部

除了美國(guó)外,日本的核電站也受到了千年蟲的影響。在新年鐘聲敲響的兩分鐘之后,日本女川核電站突然響起警報(bào),當(dāng)時(shí)計(jì)算機(jī)發(fā)現(xiàn)某負(fù)責(zé)測(cè)量周圍海水溫度的設(shè)備出現(xiàn)了問(wèn)題。好在故障只持續(xù)了 10 分鐘左右,之后一切再次回歸平靜、并未發(fā)現(xiàn)任何嚴(yán)重狀況。

日本志賀核電站也發(fā)生了類似的事件,千年蟲故障導(dǎo)致該站部分警報(bào)系統(tǒng)下線。更糟糕的是,政府辦公室的一臺(tái)電站監(jiān)控電腦與配套警報(bào)系統(tǒng)也一同宕機(jī)。總之,當(dāng)天日本各地都出現(xiàn)了類似的小問(wèn)題,不過(guò)很快得到了控制與糾正。日本官員們并沒(méi)有透露這些事件是否與千年蟲 bug 相關(guān)。

由于 Y2K 錯(cuò)誤,香港期貨交易所的計(jì)算機(jī)系統(tǒng)出現(xiàn)故障,控制恒生指數(shù)期權(quán)合約定價(jià)的計(jì)算機(jī)系統(tǒng)計(jì)算錯(cuò)了許多期權(quán)交易的交易日和到期日之間的天數(shù);芝加哥聯(lián)邦儲(chǔ)備銀行無(wú)法完成 700,000 美元的稅款轉(zhuǎn)移;芝加哥的一家銀行中斷了對(duì)部分醫(yī)院的電子醫(yī)療保險(xiǎn)支付功能,處理和支付醫(yī)療保險(xiǎn)索賠的保險(xiǎn)公司必須通過(guò)聯(lián)邦快遞,將包含已處理索賠信息的軟盤寄給銀行來(lái)保證按時(shí)付款。

此外,還有一些讓人哭笑不得的事情:

千年蟲導(dǎo)致新生兒被登記為百歲老人。丹麥的第一名“千禧嬰兒”剛剛降生就被醫(yī)院計(jì)算機(jī)登記為百歲老人。德國(guó)德意志歌劇院的計(jì)算機(jī)系統(tǒng)在 2000 年 1 月 1 日將日期跳轉(zhuǎn)回 1900 年,導(dǎo)致所有員工及其子女的年齡都發(fā)生了巨大變化。1990 年出生的小朋友瞬間迎來(lái) 90 歲高齡,并導(dǎo)致不少員工無(wú)法正常收取由政府直接在工資中發(fā)放的兒童撫育補(bǔ)貼。

完全沒(méi)用、又不能退貨的“千年蟲生存包”。借著全球各地對(duì)千年蟲大災(zāi)難的恐懼心理,不少公司提前幾個(gè)月推出了一系列“千年蟲生存包”。這個(gè)業(yè)務(wù)很快催生出價(jià)值數(shù)百萬(wàn)美元的市場(chǎng),其中一家名為 Preparedness Resources 的公司甚至通過(guò)推銷包含脫水食品、凈水器、無(wú)電池手電筒、毯子和防水火柴的生存工具套裝賺到 1600 萬(wàn)美元。頭腦清醒的總裁 Scott Sperry 還一早就定下了“售出不退”的強(qiáng)硬政策。

“一夜暴富”的驚喜體驗(yàn)。千年蟲讓德國(guó)的某個(gè)男子在新世紀(jì)的第一天突然體驗(yàn)了把當(dāng)富豪的感覺。當(dāng)天,他的銀行賬戶中隨機(jī)存入約 600 萬(wàn)美元,交易日期為 1899 年 12 月 30 日。當(dāng)時(shí)的官員并不確定這筆異常轉(zhuǎn)賬跟千年蟲有沒(méi)有關(guān)系,唯一可以肯定的是這個(gè)男子不會(huì)真的一夜暴富。

雖然從現(xiàn)在的角度來(lái)看,當(dāng)初全世界對(duì)于千年蟲問(wèn)題的恐慌似乎沒(méi)啥必要,但這主要?dú)w功于各國(guó)提前幾年投入數(shù)千億美元進(jìn)行 bug 修復(fù)。

比爾·蓋茨在采訪中就曾強(qiáng)調(diào),千年蟲“之所以最終沒(méi)有掀起什么波瀾,是因?yàn)楦鞣秸娴牟贿z余力全力修復(fù)。如果沒(méi)有這樣的付出,全世界一定會(huì)受到巨大影響?!?/p>

“千年蟲”能躲開嗎?

早在 1999 年之前,世界各地的政府和企業(yè)就一直在努力尋找 Y2K 的修復(fù)方案。但千年蟲問(wèn)題至今還不能有效避免,千年蟲還可能再次現(xiàn)身。

和千年蟲問(wèn)題類似,32 位的 Unix 操作系統(tǒng)和 Linux 操作系統(tǒng)時(shí)間溢出問(wèn)題又稱為“2038 年問(wèn)題”,所有使用 POSIX 時(shí)間表示時(shí)間的程序都將受到影響。這個(gè)問(wèn)題是由用來(lái)寫 Unix/Linux 的 C 語(yǔ)言引起的。

C 語(yǔ)言中用 time_t 來(lái)代表時(shí)間和日期,用來(lái)記載從 1970 年 1 月 1 日到 2000 年所經(jīng)歷的秒數(shù),并以 32 位存儲(chǔ)。第一位是符號(hào)位,其余 31 位用來(lái)存數(shù)字,這 31 位數(shù)字可存儲(chǔ)的最大數(shù)字為 2147483647,最多可以用到 2038 年 01 月 19 日 03 時(shí) 14 分 07 秒。

到這個(gè)時(shí)間后,數(shù)字不會(huì)自動(dòng)增加,而會(huì)變?yōu)?-2147483648,即 1901 年 12 月 13 日 20 時(shí) 45 分 52 秒。這會(huì)導(dǎo)致很多的程序出現(xiàn)問(wèn)題,甚至崩潰。

2038 年問(wèn)題不僅比千年蟲更隱蔽,而且比之前千年蟲問(wèn)題更具有破壞力。千年蟲問(wèn)題只會(huì)導(dǎo)致應(yīng)用層的程序出現(xiàn)問(wèn)題,比如信用卡支付系統(tǒng)或管理系統(tǒng)。而“2038 年問(wèn)題”的 bug,將會(huì)影響系統(tǒng)最底層的時(shí)間控制的功能。

2020 年 2 月發(fā)布的 Linux kernel 5.6 聲稱解決了這個(gè)問(wèn)題,因此 32 位系統(tǒng)也可以運(yùn)行到 2038 年后。Linux 開發(fā)人員 Arnd Bergmann 表示,使用 GNU C Library 2.32 和 Musl libc 1.2 在 64 位 time_t 上構(gòu)建用戶時(shí)間。

雖然“2038 年問(wèn)題”這樣的系統(tǒng)性問(wèn)題可能需要長(zhǎng)時(shí)間探索解決,像微軟這種類似千年蟲的 bug,完全是可以避免的。

相關(guān)鏈接:

https://www.mentalfloss.com/article/654225/everything-you-need-perfect-winter-staycation?utm_content=infinitescroll1

https://arstechnica.com/information-technology/2022/01/exchange-server-bug-gets-a-fix-after-ruining-admins-new-years-plans/

https://www.howtogeek.com/671087/what-was-the-y2k-bug-and-why-did-it-terrify-the-world/

本文來(lái)自微信公眾號(hào)“InfoQ”(ID:infoqchina),作者:褚杏娟、核子可樂(lè),36氪經(jīng)授權(quán)發(fā)布。

關(guān)鍵詞: 千年蟲 是個(gè) 微軟

相關(guān)閱讀:
熱點(diǎn)
圖片 圖片