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

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

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다