​LabVIEW 為記憶體安全語言

概觀

​NI LabVIEW 是一種圖形化程式設計平台,廣泛運用於資料採集、儀器控制與測試自動化。傳統軟體環境雖然有記憶體安全漏洞,但 LabVIEW 的架構與設計原理各不相同。 本技術文章探討讓 LabVIEW 成為記憶體安全語言 (MSL) 的機制與功能、這些屬性與傳統程式設計語言的比較,以及對需要穩定、可靠且安全應用的開發人員有何影響。 

 

​記憶體安全是軟體安全與穩定性的關鍵。在 C 與 C++ 等語言中,傳統記憶體安全問題 (如緩衝溢位、使用後無效的錯誤,以及斜向指標) 都會造成大量的軟體瑕疵與安全漏洞。相對而言,1 LabVIEW 透過高階的資料流導向圖形化環境,排除了許多風險。 

內容

了解記憶體安全與其重要性

記憶體安全是指程式確實以定義明確且可預測的方式存取記憶體。此功能有助於預防損毀、洩漏以及超出預期限制寫入資料。這些記憶體問題可能會導致當機與未定義的行為。更糟的是,威脅行動元件會操作記憶體問題以執行任意程式碼,進而將記憶體錯誤變成嚴重的安全漏洞。記憶體安全考量包含下列類型的問題: 
 

  • 緩衝溢位—在配置記憶體的邊界外寫入。 
  • 牽引指針—存取已釋出記憶體。 
  • 無後使用—在指針解除配置後,再將指針用於記憶體位置。 
  • 記憶體洩漏—無法釋出記憶體,進而導致資源逐漸耗損。 

提供直接存取記憶體的語言 (例如使用指針) 尤其容易受到這些問題影響。相對而言,記憶體安全語言會限制或完全抽象化開發人員直接的記憶體管理。 

LabVIEW 的記憶體模型

LabVIEW 與傳統文字架構語言基本上不同。其圖形化程式設計範例以資料流原則為基礎,其中程式碼的執行是由節點之間的資料流 (即所謂的虛擬儀器或 VI) 決定。

LabVIEW 架構內建的以下層面有助於提升記憶體安全:

  • 無直接指針操作—LabVIEW 不會向開發人員提供記憶體位址或指針。
  • 自動記憶體管理—LabVIEW 會根據需要分配並取消分配記憶體給變數、陣列與結構。
  • 類型安全—LabVIEW 環境在編輯期間與執行期間強制執行強型別檢查。
  • 不可變的接線值—一旦資料進入接線 (等同於變數的圖形化值),則無法在程式中其他位置意外變更資料。
  • 參考計數與垃圾收集—LabVIEW 可管理資料的使用壽命,確保記憶體在不再使用時自動還原。

資料範例與其影響

在 LabVIEW 中,程式會透過將功能區塊與傳輸資料的接線來建構。每個區塊只能在所有必要的輸入都可用時執行,而且在產生資料之前無法存取資料位置,因此能避免記憶體競爭狀況。

 

LabVIEW NI-DAQmx 程式方塊圖

圖 1.LabVIEW 程式碼範例

這個模型自然能避免使用強制語言排序不當的作業所造成的許多程式設計錯誤。

記憶體分配管理

LabVIEW Run-Time 引擎負責所有記憶體配置與解除配置。開發人員完全不需要手動要求或釋放記憶體,因此不需承受漏電和無法在使用後出錯的風險。當陣列或叢集 (類比殼狀的資料) 增加或縮小時,LabVIEW 會以透明的方式管理相關記憶體。舉例來說,如果開發人員建立了迴圈來建立陣列,LabVIEW 會自動調整陣列大小並管理相關的記憶體空間。當陣列變數超出範圍時,LabVIEW 的垃圾收集器就會回收記憶體。

邊界檢查

在 VI 編譯與執行期間,LabVIEW 開發環境會執行嚴格的類型檢查。若嘗試連接不相容的資料類型,會在編輯期間遇到這樣的問題,以避免執行階段出錯。此外,陣列與字串作業還會進行邊界檢查,以防止緩衝區溢位。

缺乏低層記憶體控制

最有效的防護措施之一,就是缺乏低階記憶體控制:LabVIEW 沒有任何機制可讓使用者執行任意指針運算,或直接存取記憶體。 這種設計表示,C 或組件常見的漏洞 (例如堆疊或堆疊溢位) 無法在原生 LabVIEW 程式碼中發生。

比較分析:LabVIEW 記憶體安全傳統語言

為了進一步了解 LabVIEW 的記憶體安全性,最好將其與 C、C++ 甚至是 Java 或 Python 等語言進行比較。

  • C/C++—這些語言可直接存取記憶體、需要手動管理記憶體,且容易受諸多記憶體安全錯誤影響。CISA 建議不要在新專案中使用 C/C++。
  • Java/Python:這些語言提供自動記憶體管理功能,但仍可提供部分間接記憶體錯誤。舉例來說,許多 Python 基礎模組都是以 C 語言編寫而成,而這些模組中的錯誤可能會在 Python 應用程式中造成記憶體問題。Python 也不會像其他 MSL 一樣在執行階段強制執行記憶體安全規則。
  • LabVIEW:LabVIEW 不提供指針,並使用嚴格型別檢查與完全受管的記憶體,大幅降低攻擊面與錯誤風險。LabVIEW 可讓使用者呼叫以 C/C++ 編寫的 DLL,因此可能會導致記憶體問題。

 

總而言之,LabVIEW 的設計可排除整個類別的記憶體相關漏洞 (例如緩衝區溢位),並簡化安全應用開發,相較於 C 和 C++ 等傳統語言,其功能具有與 Python 和 Java 相似的保護功能。

使用 LabVIEW 進行安全應用優點

LabVIEW 的記憶體安全可為開發人員、組織與一般使用者帶來實際的優勢:

  • 降低安全漏洞的風險—消除緩衝溢位與指針使用不當,即可關閉許多常見的攻擊向量。
  • 更高的穩定性—由於難以找到的記憶體錯誤,因此應用程式的當機可能性較低。
  • 加快開發速度—開發人員可專心了解應用邏輯,無需擔心記憶體配置或解除配置錯誤。
  • 更輕鬆維護—LabVIEW 程式碼較不容易出微妙、低階錯誤,因此除錯與維護作業不僅耗時又昂貴。
  • 安全關鍵用途—LabVIEW 常用於穩定性的環境,例如實驗室自動化、工業控制與科學研究。

預防緩衝溢位

如果資料超出固定長度緩衝的邊界,會覆寫鄰近記憶體,並有機會允許執行任意程式碼,就會發生傳統緩衝溢位。在 LabVIEW 中,陣列與字串作業一律經過邊界檢查。若嘗試在陣列或字串末端寫入,則會導致執行階段錯誤,而非靜態記憶體損壞。

潛在限制最佳實務

就像任何記憶體安全環境一樣,了解 LabVIEW 的界限也非常重要:

  • 外部程式碼整合—若您使用 Call Library Function Node 呼叫 LabVIEW 的外部函式庫 (DLL、共用函式庫),如果這些函式庫本身並非安全,可能會導致記憶體安全問題。
  • 資源消耗—無限迴圈或不受控制的記憶體分配仍有可能導致記憶體消耗,但不會造成毀損。
  • 版本相容性—LabVIEW 不斷演進,某些行為 (例如記憶體管理最佳化) 可能會隨之改變,因此在升級或匯入舊版程式碼時,請務必注意。

為盡可能提高呼叫外部程式碼的安全性,請遵循下列最佳實務:

  • 隔離不安全程式碼:將不安全的函式庫呼叫封裝在獨立的模組或程序中。 使用微服務或 IPC (程序間通訊) 隔離記憶體不安全的程式碼。 如此一來,不安全的程式碼就會當機或記憶體損壞,不會導致整個應用程式停機。
  • 嚴格驗證輸入與輸出—記憶體損壞通常是來自不良輸入或非預期的輸出。 驗證所有傳送至不安全函式庫的資料。 使用邊界檢查、零值檢查與類型判定。
  • 採用靜態與動態分析工具—使用工具及早發現記憶體問題。使用 LabVIEW 隨附的靜態與動態記憶體工具 (LabVIEW Professional) 來測試記憶體問題。
  • 盡可能減少不安全的面積—僅讓不安全的函式庫提供必要的最低功能。 除非絕對必要,否則請勿傳遞複雜的資料結構或指針。 盡可能保持介面簡單明瞭。
  • 稽核與監控—定期稽核由 LabVIEW 程式呼叫的外部程式碼。 

LabVIEW 協助開發人員自信進行建置

LabVIEW 的設計以圖形化資料流範例為基礎、強大的類型檢查、自動記憶體管理,而且沒有直接指針操作,可提供高度記憶體安全的環境。開發人員可從降低記憶體相關錯誤的風險、提高生產力,以及自信地為嚴苛的安全關鍵產業建立應用。

雖然沒有任何環境能夠完全抵禦錯誤,尤其是與不安全的外部元件互動時,LabVIEW 相較於傳統的文字架構語言,記憶體安全的難度也大幅提升。對於在量測、自動化與控制應用領域尋求穩定性與安全性的組織,LabVIEW 是記憶體安全開發的絕佳選擇。

方面C/C++Python/JavaLabVIEW
記憶體存取直接存取記憶體無直接存取記憶體無直接存取記憶體
記憶體管理手動管理記憶體,容易出錯自動記憶體管理自動記憶體管理
錯誤敏感性記憶體安全錯誤的風險高 (例如緩衝溢位)因嚴格的型別檢查與受管記憶體,大幅降低風險因嚴格的型別檢查與受管記憶體,大幅降低風險
指針廣泛使用指針,提高了複雜度與風險不直接使用指針不直接使用指針
安全由於手動處理記憶體並容易受到緩衝溢位,因此攻擊面較高攻擊面最小化,免疫緩衝溢位與指針利用攻擊面最小化,免疫緩衝溢位與指針利用

1 "記憶體安全語言:Reducing Vulnerabilities in Modern Software Development,” Cybersecurity and Infrastructure Agency, 2025 年 6 月,https://www.cisa.gov/resources-tools/resources/memory-safe-languages-reducing-vulnerabilities-modern-software-development.

 

Java 是 Oracle 及/或其關係企業的註冊商標。其他名稱可能為各自所有者的商標。