2038년 문제

Year 2038 problem
버그가 작동하는 애니메이션 영상입니다. 오버플로 오류는 2038년 1월 19일 03:14:08 UTC에 발생합니다.

2038년 문제(Y2038,[1] Y2K38, Y2K38 superbug 또는 Epochalypse라고도[2][3] 함)는 컴퓨터 시스템에서 시간 포맷 버그로 2038년 1월 19일 03:14:07 UTC 이후의 시간을 나타냅니다.

이 문제는 유닉스 시간(1970년 1월 1일 00:00:00 UTC)을 측정하여 부호화된 32비트 정수에 저장하는 시스템에서 발생합니다. 데이터 유형은 -(231)와 2 - 131 사이의 정수만 나타낼 수 있습니다. 즉, 올바르게 인코딩할 수 있는 가장 최근의 시간은 에포크(2038년 1월 19일 03:14:07 UTC) 후 231 - 1초입니다. 다음 초(03:14:08)까지 증가를 시도하면 정수가 오버플로우되고, 정수 값은 -(231)로 설정되며, 시스템은 에포크 2초31 전(1901년 12월 13일 20:45:52 UTC)으로 해석됩니다. 그 문제는 2000년 문제와 성격이 비슷합니다. 부호 없는 32비트 정수에 대한 유사한 저장 제약 조건은 2106년에 도달할 것입니다.

Y2038 문제가 해결되지 않으면 중요한 계산을 위해 시간을 사용하는 컴퓨터 시스템은 치명적인 오류가 발생할 수 있습니다. 미래 날짜를 사용하는 일부 응용 프로그램에서 이미 버그가 발생했습니다. 가장 취약한 시스템은 레거시임베디드 시스템과 같이 자주 업데이트되지 않거나 업데이트되지 않는 시스템입니다. 이 문제를 해결하기 위해 많은 현대 시스템은 부호가 붙은 64비트 정수를 사용하여 유닉스 시간을 측정하도록 업그레이드되었으며, 이는 우주의 추정 나이의 약 21배인 2,920억 년이 걸릴 것입니다.

원인

많은 컴퓨터 시스템은 시간과 날짜를 디지털 시간 기록을 위한 국제 표준인 유닉스 시간으로 측정합니다. 유닉스 시간은 1970년 1월 1일 0:00:00 UTC 이후 경과된 초수로 정의됩니다(유닉스 시대라고 불리는 최초의 유닉스 시스템의 생성에 따라 임의로 선택된 시간).[4]

유닉스 타임은 역사적으로 부호화된 32비트 정수(signed 32bit integer)로, 정수 값을 나타내는 32개의 이진 숫자(비트)로 구성된 데이터 유형이며, '부호'는 숫자가 양수와 음수를 모두 나타낼 수 있을 뿐만 아니라 0도 나타낼 수 있음을 의미하며, 일반적으로 두 개의 보형 형식으로 저장됩니다.[a] 따라서 부호화된 32비트 정수는 -(231)부터 2 - 1까지의31 정수 값만 나타낼 수 있습니다. 따라서 부호 32비트 정수를 사용하여 유닉스 시간을 저장할 경우 저장할 수 있는 가장 최근의 시간은 에포크 후 231 - 1(2,147,483,647)초이며, 이는 2038년 1월 19일 화요일 03:14:07입니다.[5] 에포크(03:14:08) 후에 이 값을 1초에서 2초까지31 더 증가시키려 하는 시스템은 실수로 부호 비트를 뒤집어서 음수를 나타냅니다. 이것은 정수 값을 -(231), 에포크(epoch31)보다 2초 전으로 변경하며, 이는 1901년 12월 13일 금요일 20:45:52로 해석됩니다. 여기에서 시스템은 계속 카운트업을 하고 0을 향해, 그리고 다시 양의 정수를 통해 카운트업을 할 것입니다. 많은 컴퓨터 시스템이 중요한 기능을 실행하기 위해 시간 계산을 사용하기 때문에 버그는 치명적인 오류를 유발할 수 있습니다.

취약한 시스템

32비트 시간 표현이 있는 데이터 구조를 사용하는 모든 시스템에는 고장 위험이 내재되어 있습니다. 이러한 데이터 구조의 전체 목록을 도출하는 것은 사실상 불가능하지만 유닉스 시간 문제가 있는 잘 알려진 데이터 구조가 있습니다.

  • 32비트를 사용하여 시간을 inode로 나타내는 파일 시스템
  • 32비트 시간 필드가 있는 이진 파일 형식
  • 32비트 시간 필드가 있는 데이터베이스
  • SQL과 같은 데이터베이스 쿼리 언어 UNIX_TIMESTAMP()-like 명령어

임베디드 시스템

계산 또는 진단 로깅을 위해 날짜를 사용하는 임베디드 시스템의 경우 Y2038 문제의 영향을 받을 가능성이 가장 높습니다.[1] 컴퓨터 시스템 기술의 최신 18-24개월 세대 업데이트에도 불구하고 임베디드 시스템은 구성 요소인 기계의 수명을 유지하도록 설계되었습니다. 이러한 시스템 중 일부는 2038년에도 여전히 사용될 수 있습니다. 이러한 시스템을 실행하는 소프트웨어를 업그레이드하는 것이 비실용적이거나 경우에 따라 불가능할 수 있으며, 32비트 제한을 수정하려면 결국 교체가 필요합니다.

비행에서 자동차에 이르는 많은 운송 시스템은 임베디드 시스템을 광범위하게 사용합니다. 자동차 시스템에서 여기에는 ABS(Anti-lock braking system), 전자 안정성 제어(ESC/ESP), 트랙션 제어(TCS) 및 자동 사륜 구동이 포함될 수 있습니다. 항공기는 관성 유도 시스템GPS 수신기를 사용할 수 있습니다.[b] 임베디드 시스템의 또 다른 주요 용도는 정확한 시간과 날짜를 저장하는 데 의존하고 점점 더 유닉스 계열 운영 체제를 기반으로 하는 휴대폰과 인터넷이 가능한 어플라이언스(예: 라우터, 무선 액세스 포인트, IP 카메라)를 포함한 통신 장치입니다. 예를 들어 Y2038 문제로 인해 32비트 Android를 실행하는 일부 장치가 해당 날짜로 시간을 변경해도 다시 시작되지 않습니다.[6]

그러나 많은 시스템이 날짜에 액세스할 필요가 없기 때문에 모든 임베디드 시스템이 Y2038 문제를 겪고 있다는 것을 의미하지는 않습니다. 그렇게 하는 경우, 시간/날짜 간의 차이만 추적하고 절대적인 시간/날짜는 추적하지 않는 시스템은 계산의 특성상 큰 문제를 겪지 않습니다. CAB(California Air Resources Board)와 같은 법제화된 표준에 근거한 자동차 진단의 경우가 이에 해당합니다.[7]

초기문제

2006년 5월, AOL 서버 소프트웨어에서 Y2038 문제가 초기에 나타났다는 보고가 나왔습니다. 이 소프트웨어는 "절대" 타임아웃해서는 안 되는 데이터베이스 요청을 처리하기 위해 슬러지로 설계되었습니다. 초기 설계는 이 특수한 경우를 구체적으로 다루기보다는 단순히 미래의 임의의 타임아웃 날짜를 지정했습니다. 서버의 기본 구성은 10억 초 후에 요청이 시간 초과되어야 한다고 지정했습니다. 2006년 5월 13일 UTC 01:27:28 이후 10억 초(31년 251일 1시간 46분 40초)는 2038년 컷오프일을 초과합니다. 따라서 이 시간이 지나면 타임아웃 계산이 오버플로우되어 실제로 과거에 있었던 날짜를 반환하여 소프트웨어가 충돌하게 됩니다. 문제가 발견되었을 때 AOLServer 운영자는 구성 파일을 편집하고 제한 시간을 더 낮은 값으로 설정해야 했습니다.[8][9]

솔루션

2038년 문제에 대한 보편적인 해결책은 없습니다. 예를 들어, C 언어에서 정의에 대한 모든 변경은 time_t 데이터 유형은 날짜 및 시간 표현이 서명된 32비트의 특성에 의존하는 모든 애플리케이션에서 코드 compat성 문제를 초래할 수 있습니다. time_t 정수의 예를 들어, 변경하기 time_t 부호가 없는 32비트 정수의 경우 범위가 2106(특히 2106년 2월 7일 일요일 06:28:15 UTC)으로 확장됩니다. 이러한 날짜는 음수로 표시되므로 1970년 이전 날짜를 저장, 검색 또는 조작하는 프로그램에 악영향을 미칩니다. 크기를 증가시키는 것 time_t 기존 시스템에서 64비트로 입력하면 구조의 레이아웃과 함수의 이진 인터페이스에 호환되지 않는 변경이 발생합니다.

64비트 하드웨어에서 실행되도록 설계된 대부분의 운영 체제가 이미 서명된 64비트를 사용함 time_t 정수 부호가 붙은 64비트 값을 사용하면 우주의 예상 나이보다 20배 이상 많은 새로운 랩어라운드 날짜(약 2,920억 년 후)가 도입됩니다.[10] 날짜에 계산할 수 있는 능력은 다음과 같은 사실에 의해 제한됩니다. tm_year 는 해당 연도의 1900부터 시작하는 부호화된 32비트 정수 값을 사용합니다. 이는 1년을 최대 2,147,485,547(2,147,483,647 + 1900)로 제한합니다.[11]

([12][13]일반적으로 1970년 1월 1일 또는 2000년 1월 1일) 에포크 이후 밀리초 또는 마이크로초를 부호화된 64비트 정수로 저장하여 마이크로초 해상도에서 최소 300,000년 범위를 제공하는 것과 같은 대안적인 제안이 있었습니다. 특히 자바가 모든 곳에서 64비트 길이의 정수를 사용하여 시간을 "1970년 1월 1일 이후 밀리초"로 표시하는 것은 향후 2억 9200만 년 동안 올바르게 작동할 것입니다. 새로운 시간 표현에 대한 다른 제안들은 (거의 항상 32비트보다 넓은) 다른 정확도, 범위 및 크기를 제공할 뿐만 아니라 윤초 처리와 같은 다른 관련 문제들을 해결합니다. 특히 TAI64는[14] 두 번째 및 기준 프레임을 정의하기 위한 현재 국제 실시간 표준인 TAI(International Atomic Time) 표준을 구현한 것입니다.

구현된 솔루션

  • Ruby 버전 1.9.2부터는 32비트 시스템에서 서명된 64비트 정수에 시간을 저장하여 2038년 버그를 수정합니다.[15] time_t.[16]
  • NetBSD 버전 6.0(2012년 10월 출시)부터 NetBSD 운영 체제는 64비트를 사용합니다. time_t 32비트 및 64비트 아키텍처 모두에 사용할 수 있습니다. 32비트를 사용하는 이전 NetBSD 릴리스용으로 컴파일된 애플리케이션 time_t 는 이진 호환성 계층을 통해 지원되지만 이러한 오래된 애플리케이션은 여전히 Y2038 문제로 인해 어려움을 겪을 것입니다.[17]
  • 2014년 5월에 출시된 버전 5.5 이후의 OpenBSD도 64비트를 사용합니다. time_t 32비트 및 64비트 아키텍처 모두에 사용할 수 있습니다. NetBSD와 달리 이진 호환성 계층은 없습니다. 따라서 32비트를 기대하는 애플리케이션 time_t 그리고 다른 것을 사용하는 애플리케이션 time_t 시간 값을 저장할 수 있습니다.[18]
  • 리눅스는 원래 64비트를 사용했습니다. time_t 64비트 아키텍처의 경우에만 해당됩니다. 하위 호환성 때문에 순수한 32비트 ABI는 변경되지 않았습니다.[19] 2020년 버전 5.6부터 64비트 time_t 는 32비트 아키텍처에서도 지원됩니다. 이것은 주로 내장된 Linux 시스템을 위해 수행되었습니다.[20]
  • FreeBSD는 64비트를 사용합니다. time_t 서명된 32비트를 사용하는 32비트 i386을 제외한 모든 32비트 및 64비트 아키텍처의 경우 time_t 대신에[21]
  • Linux용 x32 ABI(32비트 주소를 가진 프로그램에 대한 환경을 정의하지만 프로세서를 64비트 모드로 실행)는 64비트를 사용합니다. time_t. 새로운 환경이었기 때문에 특별한 호환성 예방 조치가 필요하지 않았습니다.[19]
  • 네트워크 파일 시스템 버전 4에서 시간 필드를 다음과 같이 정의했습니다. struct nfstime4 {int64_t seconds; uint32_t nseconds;} 2000년 [22]12월부터 seconds 필드의 값이 0보다 크면 1970년 1월 1일 0시간 이후의 날짜를 나타냅니다. 초 필드의 값이 0보다 작으면 1970년 1월 1일 0시간 이전 날짜를 나타냅니다. 두 경우 모두 nseconds(나노초) 필드가 최종 시간 표현을 위해 seconds 필드에 추가됩니다.
  • ext4 파일 시스템은 128바이트보다 큰 inode 크기로 사용되는 경우 타임스탬프당 추가 32비트 필드가 있으며, 이 중 30비트는 타임스탬프의 나노초 부분에 사용되며, 나머지 2비트는 타임스탬프 범위를 2446년까지 확장하는 데 사용됩니다.[23]
  • 리눅스 5.10부터 시작되는 XFS 파일 시스템에는 타임스탬프 범위를 2486년까지 확장하는 선택적인 "큰 타임스탬프" 기능이 있습니다.[24]
  • OpenVMS의 네이티브 API는 31086년 7월 31일까지 타임스탬프를 지원할 [25]수 있지만 C 런타임 라이브러리(CRTL)는 32비트 정수를 사용합니다. time_t.[26]1998년에 수행된 Y2K 컴플라이언스 작업의 일환으로[26] CRTL은 부호화되지 않은 32비트 정수를 사용하여 시간을 나타내도록 수정되었습니다. time_t 2106년 2월 7일까지.[27]
  • MySQL 8.0.28 기준, 기능들 FROM_UNIXTIME(), UNIX_TIMESTAMP(),그리고. CONVERT_TZ() 64비트 값을 지원하는 플랫폼에서 처리합니다. 여기에는 64비트 버전의 Linux, MacOS 및 Windows가 포함됩니다.[28] 2021년 8월 이전의 관계형 데이터베이스 버전에서는 다음과 같은 기능이 내장되어 있습니다. UNIX_TIMESTAMP() 2038년 1월 19일 UTC 03:14:07 이후에 0으로 돌아옵니다.[29]

참고 항목

  • 시간 포맷 저장 버그는 올해 2038 문제의 원인과 유사한 롤오버로 인해 종종 발생하는 다른 유사한 문제를 나열합니다.
  • GPS 주간 번호 롤오버는 공교롭게도 올해 2038년 문제와는 다른 이유로 2038년 후반에 발생할 예정입니다.

메모들

  1. ^ 특별한 규정이 없는 한, 이 문서에 제공된 모든 숫자는 서명된 정수 산술에 대한 두 사람의 칭찬을 사용하여 도출되었습니다.
  2. ^ GPS는 GPS 주간 번호 롤오버(Week Number Rollover)로 알려진 자체 시간 카운터 오버플로 문제를 겪고 있습니다.

참고문헌

  1. ^ a b "Is the Year 2038 problem the new Y2K bug?". The Guardian. 17 December 2014. Retrieved 11 October 2018.
  2. ^ Bergmann, Arnd (6 February 2020). "The end of an Era". Linaro.
  3. ^ Wagenseil, Paul (28 July 2017). "Digital 'Epochalypse' Could Bring World to Grinding Halt". Tom's Guide.
  4. ^ "Epoch Time". unixtutoria. Retrieved 13 April 2023.
  5. ^ Diomidis Spinellis (2006). Code quality: the open source perspective. Effective software development series in Safari Books Online (illustrated ed.). Adobe Press. p. 49. ISBN 978-0-321-16607-4.
  6. ^ "ZTE Blade running Android 2.2 has 2038 problems". Retrieved 20 November 2018.
  7. ^ "ARB Test Methods / Procedures". ARB.ca.gov. California Air Resources Board. Archived from the original on 18 November 2016. Retrieved 12 September 2013.
  8. ^ "The Future Lies Ahead". 28 June 2006. Retrieved 19 November 2006.
  9. ^ 2006년 5월 12일 AOL 서버 3.4.2/3.x의 이상한 "메모리 누출" 문제
  10. ^ "When does the 64-bit Unix time_t really end?". Retrieved 24 September 2022.
  11. ^ Felts, Bob (17 April 2010). "The End of Time". Stablecross.com. Retrieved 19 March 2012.
  12. ^ "Unununium Time". Archived from the original on 8 April 2006. Retrieved 19 November 2006.
  13. ^ Sun Microsystems. "Java API documentation for System.currentTimeMillis()". Retrieved 29 September 2017.
  14. ^ "TAI64".
  15. ^ "Ruby 1.9.2 is released". 18 August 2010. Retrieved 1 April 2022.
  16. ^ "time.c: use 64bit arithmetic even on platforms with 32bit VALUE".
  17. ^ "Announcing NetBSD 6.0". 17 October 2012. Retrieved 18 January 2016.
  18. ^ "OpenBSD 5.5 released (May 1, 2014)". 1 May 2014. Retrieved 18 January 2016.
  19. ^ a b Jonathan Corbet (14 August 2013). "Pondering 2038". LWN.net. Archived from the original on 4 March 2016. Retrieved 9 March 2016.
  20. ^ "LKML: Arnd Bergmann: [GIT PULL] y2038: core, driver and file system changes". lkml.org. Retrieved 30 January 2020.
  21. ^ "arch". www.freebsd.org.
  22. ^ Haynes, Thomas; Noveck, David, eds. (March 2015). "Structured Data Types". Network File System (NFS) Version 4 Protocol. sec. 2.2. doi:10.17487/RFC7530. RFC 7530.
  23. ^ "ext4 Data Structures and Algorithms". Retrieved 13 September 2022.
  24. ^ Michael Larabel (15 October 2020). "XFS File-System With Linux 5.10 Punts Year 2038 Problem To The Year 2486". Phoronix. Retrieved 13 September 2022.
  25. ^ "Why is Wednesday, November 17, 1858 the base time for OpenVMS (VAX VMS)?". Stanford University. 24 July 1997. Archived from the original on 24 July 1997. Retrieved 8 January 2020.
  26. ^ "VSI C Run-Time Library Reference Manual for OpenVMS Systems" (PDF). VSI. November 2020. Retrieved 17 April 2021.
  27. ^ "OpenVMS and the year 2038". HP. Retrieved 17 April 2021.
  28. ^ "What Is New in MySQL 8.0". dev.mysql.com.
  29. ^ "MySQL Bugs: #12654: 64-bit unix timestamp is not supported in MySQL functions". bugs.mysql.com.

외부 링크