Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

y2038 issue

1,468 views

Published on

Discuss impact and solution of y2038 issue on Linux kernel/ driver and glibc/ userspace application with 32-bit machine.

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

y2038 issue

  1. 1. Year 2038 - Storm is Brewing Harder Better Faster Stronger SZ LIN szlin@cs.nctu.edu.tw 1 Date: 2016/6/28
  2. 2. 2 SZLIN (林上智)  Debian Developer  Industrial Grade Linux Distribution R&D  https://szlin.me About Me
  3. 3. 3
  4. 4. 4 Why no more year after 2037 ? [2]
  5. 5. 5 What will be happening on 03:14:08 UTC 19 January 2038 With 32-bit Platform
  6. 6. 6 ref: https://commons.wikimedia.org/wiki/File:Year_2038_problem.gif
  7. 7. “time_t” stores system time Since: midnight UTC of January 1, 1970 7 The time_t datatype is a data type in the ISO C library and kernel structure defined for storing system time values. 32-bit system can represent dates from [2]  Dec 13 1901  Jan 19th 2038 It causes integer overflowing on 03:14:08 UTC 19 January 2038
  8. 8. 8 time_t definition in kernel space time_t definition in user space
  9. 9. Kernel-based solutions 9 non-Y2038-safe User Space Kernel Space libc system calls POSIX
  10. 10. 10
  11. 11. Why 32-bit system [1] 11 1 Long-term Support there are 32-bit systems being deployed now that can be expected to have lifetimes of 24 years or longer. 2 64-bit is Overkill 32-bit systems are likely to continue to be made for far longer than most people might expect. (e.g., micro-controller)
  12. 12. OpenBSD solution Be suitable for self-contained system 12 Changes types like time_t and clock_t to 64-bit quantities [3] DANGER: ABI incompatibility. Updating to this kernel requires extra work or you won't be able to login: install a snapshot instead. [3]
  13. 13. Linux solution Compatible, Compatible, Compatible 13 "compatibility"
  14. 14. Kernel Space Something to Change 14 Replace unsafe value/ structure Syscall Use monotonic clock instead of wall time Filesystem Timestamps
  15. 15. Replace unsafe value/ structure time_t/ timeval/ timespec to ktime_t/ timespec64 15
  16. 16. Replace unsafe value/ structure Use ktime_t instead of struct timeval [12] 16
  17. 17. Replace unsafe value/ structure ipv4: tcp_probe: Replace timespec with timespec64 [13] 17
  18. 18. Syscall is not y2038 safe kernel/time/time.c 18
  19. 19. converting system calls to 64-bit time_t [15] 19 All system calls are changed to 64-bit type and added CONFIG_COMPAT_TIME for compatibility, but it is not accepted by kernel so far [15]
  20. 20. converting system calls to 64-bit time_t [15] 20
  21. 21. Current Syscall with y2038 (1/4) syscalls that are impacted by 64-bit time_t [14] 21 class syscall name argument direction replacement range needed 64-bit argument alternatives incompatible args clocks time time_t out clock_gettime stime time_t in clock_settime gettimeofday timeval out clock_gettime settimeofday timeval in clock_settime adjtimex timex inout clock_adjtime nanosleep timespec inout clock_nanosleep clock_gettime timespec out 64 timespec64 ktime_t? - clock_settime timespec inout 64 timespec64 ktime_t? - clock_adjtime timex inout 64 timex64 ktime_t? - clock_getres timespec out 32 timespec64 ktime_t? - clock_nanosleep timespec inout 64 timespec64 ktime_t? - alarm int in timer_settime
  22. 22. Current Syscall with y2038 (2/4) syscalls that are impacted by 64-bit time_t [14] 22 class syscall name argument direction replacement range needed 64-bit argument alternatives incompatible args timers getitimer itimerval out timer_gettime setitimer itimerval inout timer_settime timer_gettime itimerspec out 64 itimespec64 ktime_t? - timer_settime itimerspec inout 64 itimespec64 ktime_t? - timerfd_gettime itimerspec out 64 itimespec64 ktime_t? - timerfd_settime itimerspec inout 64 itimespec64 ktime_t? - I/O select timeval inout pselect6 old_select sel_arg_structinout pselect6 pselect6 timespec inout 32 timespec64 ktime_t? fd_set, sigset ppoll timespec inout 32 timespec64 ktime_t? sigset io_getevents timespec in 32 timespec64 ktime_t? - recvmmsg timespec inout 32 timespec64 ktime_t? mmsghdr
  23. 23. Current Syscall with y2038 (3/4) syscalls that are impacted by 64-bit time_t [14] 23 class syscall name argument direction replacement range needed 64-bit argument alternatives incompatible args ipc mq_timedsend timespec in 64 timespec64 ktime_t? - mq_timedreceive timespec in 64 timespec64 ktime_t? - semtimedop timespec in 32 timespec64 jiffies? - msgctl msqid_ds out 64 msqid_ds64 - - semctl semid_ds out 64 semid_ds64 - - shmctl shmid_ds out 64 shmid_ds64 - - tasks rt_sigtimedwait timespec inout 32 timespec64 jiffies? sigset, siginfo futex timespec in 64 timespec64 ktime_t? - sched_rr_get_interval timespec out 32 timespec64 leave 32-bit - getrusage rusage (timeval) out 32 rusage64 leave 32-bit - wait4 rusage (timeval) out waitid waitid rusage (timeval) out 32 rusage64 leave 32-bit siginfo system sysinfo sysinfo out 32 leave 32-bit - -
  24. 24. Current Syscall with y2038 (4/4) syscalls that are impacted by 64-bit time_t [14] 24 class syscall name argument direction replacement range needed 64-bit argument alternatives incompatible args inodes utime utimbuf in utimensat utimes timeval in utimensat futimensat timeval in utimensat utimensat timespec in 64 timespec64 timespec64 - oldstat __old_kernel_s tat out stat64 oldlstat __old_kernel_s tat out lstat64 oldfstat __old_kernel_s tat out fstat64 newstat stat out stat64 newlstat stat out lstat64 newfstat stat out fstat64 newfstatat stat out fstatat64 stat64 stat64 out fstatat64 lstat64 stat64 out fstatat64 fstat64 stat64 out 64 stat6464 new struct - fstatat64 stat64 out 64 stat6464 new struct -
  25. 25. Fixing filesystem timestamps 25
  26. 26. Fixing filesystem timestamps EXT4 takes “extra” bit to extend timestamp size to 34-bit 26 Within this "extra" 32-bit field, the lower two bits are used to extend the 32-bit seconds field to be 34 bit wide; the upper 30 bits are used to provide nanosecond timestamp accuracy. Therefore, timestamps should not overflow until May 2446. [8]
  27. 27. Fixing EXT4 timestamps EXT4 is still not y2038 safe now [10] 27 Patch is ready but not accepted by kernel yet EXT4 has some y2038 unsafe variables
  28. 28. Current filesystem with y2038 (1/3) Overview of file systems [9] 28 file system time type expiration year 9p (9P2000) unsigned 32-bit seconds 2106 file system time type expiration year 9p (9P2000) unsigned 32-bit seconds 2106 9p (9P2000.L) signed 64-bit seconds, ns never adfs 40-bit cs since 1900 2248 affs u32 days/mins/(secs/50) 11760870 afs unsigned 32-bit seconds 2106 befs unsigned 48-bit seconds never bfs unsigned 32-bit seconds 2106 btrfs signed 64-bit seconds, 32-bit ns never ceph unsigned 32-bit second/ns 2106 cifs (smb) 7-bit years since 1980 2107 cifs (modern) 64-bit 100ns since 1601 30328 coda timespec ioctl 2038 cramfs fixed 1970 efs unsigned 32-bit seconds 2106 exofs signed 32-bit seconds 2038 ext2 signed 32-bit seconds 2038 ext3 signed 32-bit seconds 2038 ext4 (good old inodes) signed 32-bit seconds 2038 ext4 (new inodes 34 bit seconds / 30-bit ns (but broken) 2038 f2fs 64-bit seconds / 32-bit ns never
  29. 29. Current filesystem with y2038 (2/3) Overview of file systems [9] 29 file system time type expiration year fat 7-bit years since 1980, 2s resolution 2107 freevxfs unsigned 32-bit seconds/u32 microseconds 2106 fuse 64-bit second/32-bit ns never gfs2 u64 seconds/u32 ns never hfs u32 seconds since 1904 2040 hfsplus u32 seconds since 1904 2040 hostfs timespec 2038 hpfs unsigned 32-bit seconds 2106 isofs 'char' year since 1900 (fixable) 2028 jffs2 unsigned 32-bit seconds 2106 jfs unsigned 32-bit seconds/ns 2106 logfs signed 64-bit ns 2262 minix unsigned 32-bit seconds 2106 ncpfs 7-bit year since 1980 2107 nfsv2,v3 unsigned 32-bit seconds/ns 2106 nfsv4 u64 seconds/u32 ns never nfsd unsigned 32-bit seconds/ns 2106 nilfs2 u64 seconds/u32 ns never ntfs 64-bit 100ns since 1601 30828 ocfs2 34-bit seconds/30-bit ns 2514 omfs 64-bit milliseconds never pstore ascii seconds 2106
  30. 30. Current filesystem with y2038 (3/3) Overview of file systems [9] 30 file system time type expiration year qnx4 unsigned 32-bit seconds 2106 qnx6 unsigned 32-bit seconds 2106 reiserfs unsigned 32-bit seconds 2106 romfs fixed 1970 squashfs unsigned 32-bit seconds 2106 sysv unsigned 32-bit seconds 2106 ubifs u64 second/u32 ns never udf u16 year 2038 ufs1 unsigned 32-bit seconds 2106 ufs2 signed 64-bit seconds/u32 ns never xfs signed 32-bit seconds/ns 2106
  31. 31. Fixing VFS with y2038 31
  32. 32. Plan for VFS with y2038 [9] 32 Milestone # of patches Status Targeted Kernel release Infrastructure patches for vfs_time and granularity fields 1.4.1 and 1.4.2 2 Done 4.7- rc1 Test time ranges beyond y2038 support, in memory timestamps match with on disk -1.3.1 and 1.3.2 Xfs tests In progress 5/28/16 Replace CURRENT_TIME and CURRENT_TIME_SEC – 1.2.1 ~60 In Progress, waiting for 4.7 rc1 and repost previous. 4.8 Vfs_time patches – 1.4.3 ~40 In Progress, waiting for 4.7-rc1 4.8 Fill in right granularities and ranges for FS – 1.2.2 and 1.2.3 ~40 Yet to start 4.8 Expose FS granularities and ranges – 1.4.5 and 1.4.6 ~5 Yet to start 4.8 Tests to check the granularities and ranges – 1.3.3 and 1.3.4 Xfs tests Yet to start 6/10/16 Add policy for wrong granularities - 1.4.7 RFC for 4.9 Yet to start Stat and utime changes – 1.4.8 RFC for 4.9 Yet to start Tests for I_DIRTY_* flags and mount options -1.3.5 and 1.3.6 Xfs tests Yet to start 6/30/16 Transition vfs to 64 bit – 1.4.4 2 Ready, wait for other patches to merge 4.10
  33. 33. Use monotonic clock instead of wall time 33 y2038 unsafe. an integer overflow might be occurred
  34. 34. Use monotonic clock instead of wall time 34 y2038 safe
  35. 35. User space [5] 35
  36. 36. User space 36 Kernel and GLIBC might be incompatible 1 32-bit/ 64-bit use the same name of APIs User need to define application code “_TIME_BITS=64” to get 64-bit time support 32-bit time APIs are default setting on 32-bit systems On 32-bit systems, if __USE_TIME_BITS64 is defined, time support is provided for 64-bit time; otherwise, it is provided for 32-bit time.[5] 2
  37. 37. Definite & Debatable [5] 37 Definite 1. 64-bit time would be supported as a replacement of 32-bit time; user code (including libraries) would require either 32-bit or 64-bit time support, with 32-bit remaining the default for now. 2. Any newly introduced function MUST be declared in the implementation, not user, namespace (see https://sourceware.org/bugzilla/show_bug.cgi?id=14106). 3. Any newly introduced struct MUST have a name (see https://sourceware.org/bugzilla/show_bug.cgi?id=15766). Debatable (Should be removed) 1. 64-bit time should only be supported if 64-bit file offsets are. This sounds like something totally unrelated, but the underlying idea is to not multiply the possible combinations. 2. 32-bit time support will not be modified; 32-bit time functions which returns wrong results now will keep returning wrong results after introduction of 64-bit time support. IOW, this design does not aim at trying to fix existing 32-bit time support at all; any fix to the Y2038 problem will be within new 64-bit time support. 3. Make sure no change affects 64-bit platforms where time_t is already 64-bit (see http://www.sourceware.org/ml/libc-alpha/2015-08/msg00038.html).
  38. 38. Time-related GLIBC APIs (1/3) [5] 38 Function Y2038-unsafe? time_t YES, as time_t is 32-bit signed on 32-bit builds double difftime (time_t time1, time_t time0) YES, as time_t is Y2038-unsafe struct timeval { time_t tv_sec; long int tv_usec; } YES, as time_t is Y2038-unsafe struct timespec { time_t tv_sec; long int tv_nsec; } YES, as time_t is Y2038-unsafe clock_t clock(void) No, return value is not clock time in seconds since the epoch but CPU time in clock ticks struct tms { clock_t tms_utime; clock_t tms_stime; clock_t tms_cutime; clo ck_t tms_cstime; } No, as all members are Y2038-safe clock_t times(struct tms *buffer) No, as struct tms is Y2038-safe time_t time (time_t *result) YES, as time_t is Y2038-unsafe int stime (const time_t *newtime) YES, as time_t is Y2038-unsafe struct timezone { int tz_minuteswest; int tz_dsttime; } No struct timeval YES, as struct timeval depends on time_t which is Y2038-unsafe int gettimeofday (struct timeval *tp, struct timezone *tzp) YES, as struct timeval is Y2038-unsafe int settimeofday (const struct timeval *tp, const struct timezone *tzp) YES, as struct timeval is Y2038-unsafe int adjtime (const struct timeval *delta, struct timeval *olddelta) YES, as struct timeval is Y2038-unsafe struct timex YES, as struct timex depends on struct timeval which is Y0238-unsafe int adjtimex (struct timex *timex) YES, as struct timex is Y0238-unsafe struct tm { int tm_sec; int tm_min; ... } No, as all members are Y2038-safe
  39. 39. Time-related GLIBC APIs (2/3) [5] 39 Function Y2038-unsafe? struct tm * localtime (const time_t *time) YES, as time_t is Y2038-unsafe struct tm * localtime_r (const time_t *time, struct tm *resultp) YES, as time_t is Y2038-unsafe struct tm * gmtime (const time_t *time) YES, as time_t is Y2038-unsafe struct tm * gmtime_r (const time_t *time, struct tm *resultp) YES, as time_t is Y2038-unsafe time_t mktime (struct tm *brokentime) YES, as time_t is Y2038-unsafe time_t timelocal (struct tm *brokentime) YES, as time_t is Y2038-unsafe time_t timegm (struct tm *brokentime) YES, as time_t is Y2038-unsafe struct ntptimeval { struct timeval time; long int maxerror; long int esterr or; } YES, as struct timeval is Y2038-unsafe struct ntptimeval YES, as struct ntptimeval depends on struct timeval which is Y2038- unsafe ntp_gettime (struct ntptimeval *tptr) YES, as struct ntptimeval is Y2038-unsafe struct timex { ... struct timeval time; ... } YES, as struct timeval time is Y2038-unsafe int ntp_adjtime (struct timex *tptr) YES, as struct timex is Y2038-unsafe char * asctime (const struct tm *brokentime) No, as struct tm is Y2038-safe char * asctime_r (const struct tm *brokentime, char *buffer) No, as struct tm is Y2038-safe char * ctime (const time_t *time) YES, as time_t is Y2038-unsafe char * ctime_r (const time_t *time, char *buffer) YES, as time_t is Y2038-unsafe size_t strftime (char *s, size_t size, const char *template, const struct tm * brokentime) No, as struct tm is Y2038-safe size_t wcsftime (wchar_t *s, size_t size, const wchar_t *template, const str uct tm *brokentime) No, as struct tm is Y2038-safe
  40. 40. Time-related GLIBC APIs (3/3) [5] 40 Function Y2038-unsafe? char * strptime (const char *s, const char *fmt, struct tm *tp ) No, as struct tm is Y2038-safe struct tm * getdate (const char *string) No, as struct tm is Y2038-safe int getdate_r (const char *string, struct tm *tp) No, as struct tm is Y2038-safe struct itimerval YES, as struct timeval depends on struct timeval which is Y2038-unsafe int setitimer (int which, const struct itimerval *new, struct i timerval *old) YES, as struct itimerval is Y2038-unsafe int getitimer (int which, struct itimerval *old) YES as struct itimerval is Y2038-unsafe unsigned int alarm (unsigned int seconds) TBC depending on implementation unsigned int sleep (unsigned int seconds) TBC depending on implementation int nanosleep (const struct timespec *requested_time, stru ct timespec *remaining) YES, as struct timespec is Y2038-unsafe
  41. 41. Other GLIBC APIs (1/2) [5] 41 Function Y2038-unsafe? Section 22.1 - Resource Usage struct rusage { struct timeval ru_utime; struct timeval ru_st ime; ... } YES, as struct_timeval is Y2038-unsafe int getrusage (int processes, struct rusage *rusage) YES, as struct_rusage is Y2038-unsafe struct vtimes { struct timeval vm_utime; struct timeval vm_ stime; ... } YES, as struct_timeval is Y2038-unsafe int vtimes (struct vtimes *current, struct vtimes *child) YES, as struct_vtimes is Y2038-unsafe Section 22.2 - Resource Limitation rlim_t No, as the value held is an amount of seconds, not an absolute date int sched_rr_get_interval (pid_t pid, struct timespec *interva l) No, as the value returned is a small interval, typically 150 µs)
  42. 42. Other GLIBC APIs (2/2) [5] 42 Function Y2038-unsafe? Section 22.1 - Resource Usage struct rusage { struct timeval ru_utime; struct timeval ru_stime; ... } YES, as struct_timeval is Y2038-unsafe int getrusage (int processes, struct rusage *rusage) YES, as struct_rusage is Y2038-unsafe struct vtimes { struct timeval vm_utime; struct timeval vm_stim e; ... } YES, as struct_timeval is Y2038-unsafe int vtimes (struct vtimes *current, struct vtimes *child) YES, as struct_vtimes is Y2038-unsafe Section 22.2 - Resource Limitation rlim_t No, as the value held is an amount of seconds, not an absolute date int sched_rr_get_interval (pid_t pid, struct timespec *interval) No, as the value returned is a small interval, typically 150 µs)
  43. 43. 43 Conclusion Be aware when coding AP/ driver with 32-bit machine Don’t use y2038-unsafe value/ structure in driver Don’t use y2038-unsafe value/ structure in application 1 2 3 The solution is not confirmed yet Keep a close eye on tracking Kernel patch GLIBC patch Upgrade existence AP/ driver The assignment of Job Factors should be completed by the junior R&D – this bug will hurt their supplemental retirement planning
  44. 44. 44 Thank you
  45. 45. 45 References 1. 2038 is closer than it seems https://lwn.net/Articles/599580/ 2. The end of time http://elinux.org/images/6/6e/End_of_Time_-- _Embedded_Linux_Conference_2015.pdf 3. CVS: cvs.openbsd.org: src http://marc.info/?l=openbsd-cvs&m=137637321205010&w=2 4. Pondering 2038 https://lwn.net/Articles/563285/ 5. Third draft of the glibc Y2038 design document https://sourceware.org/glibc/wiki/Y2038ProofnessDesign?rev=63 6. y2038 http://kernelnewbies.org/y2038 7. Heading toward 2038-safe filesystems https://lwn.net/Articles/672576/ 8. Ext4 Disk Layout https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Inode_Timestamps 9. y2038/vfs http://kernelnewbies.org/y2038/vfs 10. fs: ext4: Use current_fs_time() for inode timestamps https://patchwork.kernel.org/patch/9166291/ 11. System call conversion for year 2038 https://lwn.net/Articles/643234/ 12. isdn: Use ktime_t instead of 'struct timeval https://patchwork.kernel.org/patch/7516841/ 13. net: ipv4: tcp_probe: Replace timespec with timespec64 https://patchwork.ozlabs.org/patch/589342/ 14. posix timers:Introduce the 64bit methods with ti http://thread.gmane.org/gmane.linux.kernel.cross-arch/27249 15. converting system calls to 64-bit time_t https://lists.linaro.org/pipermail/y2038/2015-May/000233.html

×