​메모리 안전 언어로 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 런타임 엔진이 담당합니다. 개발자는 수동으로 메모리를 요청하거나 해제할 필요가 없으므로 누출과 사용 후 에러가 발생할 위험이 없게 됩니다. 배열 또는 클러스터(구조 타입의 데이터)가 커지거나 줄어들면, LabVIEW 관련된 메모리를 투명하게 관리합니다. 예를 들어, 개발자가 배열을 만드는 루프를 생성하는 경우, LabVIEW 자동으로 배열의 크기를 조정하고 관련된 메모리 공간을 관리합니다. 배열 변수가 영역을 벗어나면, LabVIEW 쓰레기 수집기가 메모리를 다시 가져옵니다.

엄격한 타이핑 및 경계 확인

LabVIEW 개발 환경은 VI 컴파일 및 실행 중에 엄격한 타입 검사를 수행합니다. 호환되지 않는 데이터 타입을 함께 연결하려는 시도는 편집 시 발생하여 런타임 에러를 방지합니다. 또한 배열과 문자열 작업에는 버퍼 오버플로우를 방지하기 위해 경계 확인이 포함됩니다.

낮은 레벨의 메모리 컨트롤이 없음

가장 효과적인 방지 방법 중 하나는 낮은 레벨의 메모리 컨트롤이 없다는 것입니다. 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 설계는 전체 범주의 메모리 관련 취약점(예: 버퍼 오버플로우)을 제거하고, 보안 어플리케이션 개발을 단순화하여, Python 및 Java와 유사한 보호 기능을 제공하는 C 및 C++와 같은 기존 언어에 비해 상당한 이점을 제공합니다.

보안 어플리케이션을 위한 LabVIEW 사용의 장점

LabVIEW 메모리 안전은 개발자, 조직, 최종 사용자에게 다음과 같은 실현 가능한 이점을 제공합니다.

  • 보안상 취약점의 위험 감소—버퍼 오버플로우와 포인터 오용을 제거하면 많은 공격 벡터가 종료됩니다.
  • 더 높은 신뢰성 - 찾기 어려운 메모리 오류로 인해 어플리케이션 충돌 가능성이 낮습니다.
  • 빠른 개발—개발자는 메모리 할당 또는 할당 해제 버그에 대해 걱정하지 않고도 어플리케이션 로직에 집중할 수 있습니다.
  • 간편한 유지관리—LabVIEW 코드는 미묘하고 낮은 레벨의 오류가 발생하는 경향이 적으므로 디버깅 및 유지보수 작업이 비싸고 시간이 많이 소요됩니다.
  • 안전 크리티컬 어플리케이션—LabVIEW는 종종 실험실 자동화, 산업 제어, 과학 연구와 같은 안정성이 가장 중요한 환경에서 사용됩니다.

버퍼 오버플로우 방지

기존 버퍼 오버플로우는 데이터가 고정된 길이 버퍼의 경계를 초과하여 인접한 메모리를 덮어쓰고 임의의 코드 실행을 가능하게 할 때 발생합니다. LabVIEW 경우, 배열과 문자열 작업은 항상 경계를 확인합니다. 배열 또는 문자열의 끝을 넘어서 쓰려고 하면 내부적인 메모리 손상이 아닌 런타임 에러가 발생합니다.

잠재적인 한계와 권장 사례

모든 메모리 안전 환경에서와 같이 LabVIEW 경계를 이해하는 것이 중요합니다.

  • 외부 코드 통합―LabVIEW에서 [라이브러리 함수 호출 노드]를 사용하여 외부 라이브러리(DLL, 공유 라이브러리)를 호출하면 해당 라이브러리가 안전하지 않은 경우 메모리 안전 문제가 발생할 수 있습니다.
  • 자원 소모―무한 루프 또는 제어되지 않는 메모리 할당은 여전히 메모리 소모로 이어질 수 있지만 손상은 아닙니다.
  • 버전 호환성—LabVIEW가 진화함에 따라 특정 동작(예: 메모리 관리 최적화)이 변경될 수 있으므로 레거시 코드를 업그레이드하거나 포팅할 때 주의해야 합니다.

외부 코드를 호출할 때 안전성을 극대화하려면 다음 권장 방법을 따르십시오:

  • 안전하지 않은 코드 절연―안전하지 않은 라이브러리 호출을 별도의 모듈 또는 프로세스에 캡슐화합니다. 마이크로서비스 또는 IPC (Process Inter-Process Communication)를 사용하여 메모리가 안전하지 않은 코드를 분리합니다. 이렇게 하면 안전하지 않은 코드에서 충돌이 발생하거나 메모리가 손상되면 어플리케이션 전체가 작동하지 않습니다.
  • 입력 및 출력 엄격한 검증—메모리 손상은 잘못된 입력 또는 예상치 못한 출력으로 인해 발생합니다. 안전하지 않은 라이브러리로 전달된 모든 데이터를 검증합니다. 경계 확인, Null 확인, 타입 지정 사용.
  • 정적 및 동적 분석 도구 사용—메모리 문제를 일찍 해결하는 도구를 사용합니다. LabVIEW Professional에 포함된 LabVIEW 정적 및 다이나믹 메모리 도구를 사용하여 메모리 문제를 테스트합니다.
  • 안전하지 않은 표면 영역 최소화―안전하지 않은 라이브러리의 최소 필요한 기능만 노출합니다. 절대적으로 필요한 경우를 제외하고 복잡한 데이터 구조 또는 포인터를 전달하지 마십시오. 인터페이스를 최대한 간단하게 정의하고 정의합니다.
  • 인증 및 모니터링—LabVIEW 프로그램이 호출하는 외부 코드를 정기적으로 감사합니다. 

LabVIEW 사용하면 개발자가 안전하게 빌드할 수 있음

그래픽 데이터 흐름 패러다임, 강력한 타입 검사, 자동 메모리 관리, 직접적인 포인터 조작이 없는 LabVIEW 설계는 높은 메모리 안전 환경을 제공합니다. 개발자는 메모리 관련 버그의 위험 감소, 생산성 향상, 안전에 중요한 요구 사항이 높은 업종을 위해 어플리케이션을 확실하게 구축할 수 있는 기능을 활용할 수 있습니다.

특히 안전하지 않은 외부 구성요소와 상호작용할 때 에러가 발생하지 않는 환경은 없지만, LabVIEW 기존의 텍스트 기반 언어에 비해 메모리의 안전성을 크게 높입니다. 측정, 자동화, 컨트롤 어플리케이션에서 안정성과 보안을 확보하고자 하는 조직의 경우, LabVIEW 메모리 안전한 개발을 위한 강력한 선택입니다.

외형C/C++Python/JavaLabVIEW
메모리 접근메모리 액세스메모리 액세스 없음메모리 액세스 없음
메모리 관리수동 메모리 관리, 에러 발생 가능자동 메모리 관리자동 메모리 관리
에러 민감도메모리 안전 에러(예: 버퍼 오버플로우)의 위험이 높음엄격한 타이핑 및 관리형 메모리로 인한 위험 감소엄격한 타이핑 및 관리형 메모리로 인한 위험 감소
포인터포인터의 광범위한 사용으로 복잡성과 위험성 증가포인터를 직접 사용하지 않음포인터를 직접 사용하지 않음
보안수동 메모리 핸들링과 버퍼 오버플로우에 취약하기 때문에 높은 공격 표면최소한의 공격 표면, 버퍼 오버플로우 및 포인터 활용에 대해 방지최소한의 공격 표면, 버퍼 오버플로우 및 포인터 활용에 대해 방지