[카테고리:] 미분류

  • Blake2b 정렬 문제의 정체

    🔷 개요: -Warray-bounds 경고가 왜 문제인가?

    Xcode 프로젝트에서 외부 라이브러리나 암호화 함수(특히 Blake2b)를 사용하다 보면 다음과 같은 컴파일 오류를 만날 수 있습니다:

    bashCopyEditerror: array subscript is partly outside array bounds [-Werror=array-bounds]
    

    이 오류는 실제 런타임에서 문제가 없을 수도 있지만, 컴파일러의 정적 분석이 위험하다고 판단한 경우에도 발생합니다. Blake2b의 SIMD 최적화 코드가 대표적인 사례입니다.


    🔍 원인 분석: Blake2b 내부 코드를 살펴보자

    Blake2b는 고속 해시 알고리즘으로, 내부적으로 직접 메모리 접근정렬된 구조체를 사용합니다.

    예시 코드: 문제의 핵심

    cCopyEdittypedef struct __attribute__((aligned(64))) blake2b_state {
      uint64_t h[8];
      uint64_t t[2];
      uint64_t f[2];
      uint8_t  buf[2 * BLAKE2B_BLOCKBYTES];  // 문제 발생 지점
      size_t   buflen;
      uint8_t  last_node;
    } blake2b_state;
    
    cCopyEditstatic void blake2b_compress(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) {
      const uint64_t *m = (const uint64_t *)block;
      // ...
      v[0] ^= m[0];   // 🔥 컴파일러가 여기서 경고를 날릴 수 있음
    }
    

    왜 경고가 나는가?

    • blockuint8_t 배열인데 uint64_t 포인터로 캐스팅됨 → 정렬 불일치 가능성 존재.
    • m[0] 접근은 8바이트 정렬이 보장되지 않으면 undefined behavior일 수 있음.
    • Clang이나 GCC는 정렬을 보장하지 못할 경우 보수적으로 경고를 발생시킴.

    ⚠️ 특히 __attribute__((aligned(64)))가 지정되어 있더라도, 이를 사용하는 코드가 정확히 정렬된 메모리를 전달하지 않으면 경고 또는 런타임 문제가 발생합니다.


    ⚙️ 해결 방법: 컴파일러 플래그로 우회

    문제가 되는 부분을 직접 수정하기보다, 대부분의 Xcode 프로젝트에서는 다음과 같이 경고를 무시하는 방식을 택합니다.

    Podfile의 예 (CocoaPods 사용 시):

    rubyCopyEditpost_install do |installer|
      installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
          config.build_settings['OTHER_CFLAGS'] = '$(inherited) -Wno-error=array-bounds'
          config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO'
        end
      end
    end
    

    의미

    설정의미
    -Wno-error=array-bounds배열 경계 초과에 대한 경고를 에러로 취급하지 않음
    GCC_WARN_ABOUT_RETURN_TYPE = NOC 코드에서 반환형 관련 경고 무시 (Blake2b 구현체가 종종 미지정 상태로 선언됨)

    🧪 대안: 코드 수정 시 고려사항

    직접 Blake2b 코드를 수정해 문제를 없애고 싶다면, 다음을 고려해야 합니다.

    1. 메모리 정렬 보장

    cCopyEdit// safer casting
    uint64_t m[16] __attribute__((aligned(64)));
    memcpy(m, block, BLAKE2B_BLOCKBYTES);
    

    2. 컴파일 타겟에 따른 차이

    • ARM64(iOS 디바이스): 정렬 문제에 더 민감
    • x86_64(macOS): 상대적으로 관대하지만, 컴파일러 설정이 보수적으로 되어 있으면 동일하게 경고 발생

    🧠 왜 이런 일이 생길까?

    핵심은 컴파일러의 정적 분석(Static Analysis)

    컴파일러는 런타임 상황을 정확히 알 수 없기 때문에 다음과 같은 보수적인 접근을 택합니다:

    • 포인터가 안전하게 정렬되지 않았다고 추정하면 경고
    • 코드가 안전하다고 사람은 알아도, 컴파일러는 모름
    • 보안상 안전하지 않은 코드를 경고로 막는 문화 → 특히 암호화 함수에서 민감함

    ✅ 실전 팁 요약

    상황해결책
    CocoaPods 사용post_install에서 -Wno-error=array-bounds 추가
    직접 코드 수정memcpy() 사용하여 안전한 정렬 캐스팅
    CMake/Makefile 프로젝트CFLAGS += -Wno-error=array-bounds 설정
    경고가 많아 디버깅 어려움-Warray-bounds 자체를 끄는 것도 고려 (단, 위험성 존재)

    🔚 결론

    Blake2b는 성능을 위해 하드코딩된 메모리 최적화를 사용하는 만큼, 컴파일러의 정적 검사와 자주 충돌합니다. 경고 무시는 빠른 해결책이지만, 실제 문제가 아닌지 확인하고 우회 설정을 적용하는 것이 가장 안전한 방식입니다.

    코드 한 줄로 해결되지만, 무시된 경고 속에 숨어있는 진짜 문제도 함께 감지하는 습관이 필요합니다.