# 64비트 time_t 전환의 위험성

> Clean Markdown view of GeekNews topic #16989. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=16989](https://news.hada.io/topic?id=16989)
- GeekNews Markdown: [https://news.hada.io/topic/16989.md](https://news.hada.io/topic/16989.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-09-30T09:48:10+09:00
- Updated: 2024-09-30T09:48:10+09:00
- Original source: [blogs.gentoo.org](https://blogs.gentoo.org/mgorny/2024/09/28/the-perils-of-transition-to-64-bit-time_t/)
- Points: 1
- Comments: 1

## Topic Body

#### 64비트 `time_t`로의 전환 위험성

- 32비트 `time_t` 타입 사용으로 인해 2038년에 32비트 애플리케이션이 오류를 일으킬 가능성이 있음
- `time_t`를 64비트 타입으로 변경하는 것이 해결책으로 제시됨
- Musl은 이미 전환 완료, glibc는 옵션으로 지원, Debian 등 여러 배포판은 전환 완료
- Gentoo와 같은 소스 기반 배포판은 전환이 어려움

##### Large File Support로 돌아가기

- 32비트 아키텍처는 파일 오프셋을 지정하는 `off_t`와 inode 번호를 지정하는 `ino_t`를 32비트로 사용
- 이로 인해 2 GiB 이상의 파일을 열 수 없고, inode 번호가 32비트 범위를 초과하는 파일을 열 수 없음
- Large File Support 도입으로 이 문제를 해결, glibc에서는 여전히 선택 사항
- time64 지원을 위해 LFS 사용이 필요

##### 어떤 ABI를 사용하는가?

- 세 가지 가능한 서브-ABI:
  1. 32비트 타입을 사용하는 원래의 ABI
  2. 64비트 `off_t`와 `ino_t`, 32비트 `time_t`를 사용하는 LFS
  3. LFS + 64비트 `time_t`를 사용하는 time64
- glibc 빌드는 세 가지 변형과 호환 가능하지만, API에서 이러한 타입을 사용하는 라이브러리는 호환되지 않음

##### 왜 ABI 변경이 나쁜가?

- 32비트 타입을 64비트 타입으로 교체하는 것은 호환성을 깨뜨림
- 구조체의 경우, `time_t`가 포함된 구조체는 필드 위치가 변경되어 잘못된 필드를 읽거나 쓸 수 있음
- 함수 매개변수의 경우, 스택에 전달되는 매개변수의 위치가 변경되어 잘못된 매개변수를 읽거나 쓸 수 있음
- 이러한 문제는 런타임 오류와 보안 문제를 야기할 수 있음

##### 어떻게 안전하게 만들 수 있는가?

- 세 가지 아이디어:
  1. 새로운 ABI를 구분하기 위해 플랫폼 튜플(`CHOST`) 변경
  2. 새로운 ABI를 위해 libdir 변경
  3. 서로 다른 서브-ABI를 사용하는 바이너리가 링크되지 않도록 바이너리 수준의 ABI 구분 도입

##### 플랫폼 튜플 변경

- 플랫폼 튜플은 툴체인이 타겟팅하는 플랫폼을 식별
- 새로운 ABI를 도입하기 위해 벤더 필드를 변경하거나 libc 필드에 추가 ABI 명세를 추가
- 예: `i686-gentoo_t64-linux-gnu`, `i686-pc-linux-gnut64`

##### libdir 변경

- libdir은 라이브러리 설치 디렉토리의 기본 이름
- time64 변형을 위해 libdir 값을 변경하여 새로운 libdir에 time64 라이브러리를 설치
- 이로 인해 time64 실행 파일이 time32 라이브러리를 링크하지 않도록 방지
- Portage의 `preserved-libs` 기능을 사용하여 기존 라이브러리를 보존

##### 바이너리 호환성 보장

- 서로 다른 ABI를 사용하는 바이너리를 혼합할 수 없음
- ELF 클래스, 머신 식별자, 플래그 필드 등을 사용하여 호환성 확인
- time32와 time64 시스템을 구분하기 위해 새로운 ELF 노트 섹션 추가 고려

##### 오래된 사전 빌드 애플리케이션

- 오래된 사전 빌드 애플리케이션은 시스템 라이브러리와의 호환성 문제와 y2k38 문제에 직면
- 멀티리브 레이아웃을 사용하여 호환성 문제 해결 가능
- y2k38 문제는 시스템 시간을 조작하거나 VM을 사용하는 방법으로 해결 가능

#### GN⁺의 정리

- 2038년 이후 32비트 `time_t`를 사용하는 애플리케이션이 오류를 일으킬 가능성이 있음
- 64비트 `time_t`로 전환이 필요하지만, 이는 ABI 변경을 수반하여 복잡한 문제를 야기함
- 플랫폼 튜플 변경, libdir 변경, 바이너리 호환성 보장을 통해 안전한 전환 경로를 제공할 수 있음
- 오래된 사전 빌드 애플리케이션은 별도의 호환성 문제와 y2k38 문제를 해결해야 함

## Comments



### Comment 29480

- Author: neo
- Created: 2024-09-30T09:48:10+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=41681266) 
- Gentoo는 패키지를 설치하지 않고 빌드하는 옵션이 부족함
  - Gentoo는 패키지 빌드와 설치가 한 단계로 이루어짐
  - ABI 변경 시 업데이트 중에 시스템이 쉽게 깨질 수 있음
  - 64비트 `time_t` 문제는 널리 알려진 ABI 변경의 예시임

- `.so` 버전 관리를 통해 ABI 변경을 처리하는 방법
  - `.so` 파일은 버전 번호를 포함함
  - 패키지 자체가 내부적으로 버전 번호를 관리함
  - 64비트 `time_t`를 지원하려면 상속된 ABI를 제어할 수 있는 추가 구성 요소가 필요함

- Mac OS X에서 `off_t`와 `ino_t`를 처리한 방법
  - 기존 호출과 구조체는 그대로 유지됨
  - 새로운 호출과 타입에 `64` 접미사가 추가됨
  - 빌드 시 컴파일된 바이너리가 실행될 최소 OS 버전을 지정할 수 있음

- Debian은 64비트 `time_t`로 전환하는 데 어려움을 겪었음
  - 소스 기반 배포판은 더 어려운 전환 과정을 겪음

- 32비트 유닉스 시스템에서 `time_t`를 unsigned 32비트로 대체한 경험
  - 2038년 이후 68년을 더 사용할 수 있게 됨
  - 유닉스 에포크 이전의 날짜를 표현할 수 없음

- FreeBSD에서 amd64 포트를 할 때 64비트 `time_t`를 도입한 경험
  - 32비트 함수 인자가 64비트로 자동 변환됨
  - 초기부터 64비트 `time_t`를 사용하여 문제를 피함
  - tzcode가 64비트 안전하지 않아서 일부 문제를 겪음

- BSD 매뉴얼 페이지의 "Bugs" 섹션에 있는 농담
  - "You can tune a file system, but you can't tune a fish."

- 소스 기반 배포판 대신 Debian 같은 비소스 기반 배포판으로 전환하고 싶다는 의견

- 32비트 `time_t`와 64비트 `time_t`의 구조체 오프셋 차이
  - 64비트 타입에서는 `b`가 64비트 정렬이 필요하여 패딩이 추가됨

- C에서 타입 별칭이 나중에 변경될 가능성을 제공한다고 생각했지만, 실제로는 그렇지 않음

- 문제를 빨리 해결하는 것이 좋다는 의견
  - OpenBSD는 모든 아키텍처에서 64비트 `time_t`를 사용함
