Linux Kernel – Fixing System-Time and RTC Time Differences in Linux

clockdatedebianlinux-kernel

I'm running Debian Stretch and Linux kernel version 4.9.110-3+deb9u4, with a modified config. I'm observing the following weird behaviour

  1. Set the hardware clock to 2016-01-01 00:00:00 UTC
  2. Reboot
  3. dmesg reports reading the hardware clock similar to what was set previously
  4. date reports 2016-11-03 17:16:42 UTC

The above behaviour is observed with any date before 2016-11-03 17:00:00 UTC. I haven't narrowed down any further than that.

The kernel source code has not been changed, nor am I running any custom kernel modules. I have also observed this with using the 4.9.168 kernel from the Debian repos, as well as the 4.19.37 kernel from stretch-backports. I have also been able to reproduce this on a DigitalOcean droplet running Stretch and 4.9.168.

I have not seen this problem occur when I set a date after 2016-11-03. It doesn't seem likely, but it seems like the kernel is forcing some minimum date.

Does anybody have a clue on this?

Logs from my VM:

root@debian-vm:~# timedatectl 
      Local time: Thu 2016-11-03 17:17:02 UTC
  Universal time: Thu 2016-11-03 17:17:02 UTC
        RTC time: Fri 2016-01-01 00:29:00
       Time zone: Etc/UTC (UTC, +0000)
 Network time on: yes
NTP synchronized: no
 RTC in local TZ: no
root@debian-vm:~# dmesg | grep rtc
[    0.985653] rtc_cmos 00:01: registered as rtc0
[    0.985670] rtc_cmos 00:01: alarms up to one month, y3k, 114 bytes nvram, hpet irqs
[    1.032409] rtc_cmos 00:01: setting system clock to 2016-01-01 00:28:37 UTC (1451608117)

Logs from a DigitalOcean droplet:

root@debian-s-1vcpu-1gb-sfo2-01:~# timedatectl                                                                                                                                                                                                                                                                                                      
      Local time: Thu 2016-11-03 17:17:05 UTC
  Universal time: Thu 2016-11-03 17:17:05 UTC
        RTC time: Fri 2016-01-01 00:00:46
       Time zone: Etc/UTC (UTC, +0000)
 Network time on: yes
NTP synchronized: no
 RTC in local TZ: no

Best Answer

It turns out that this is not in the Linux kernel, but in systemd. The systemd clock utility has a minimum clock value defined at build time, and if the time read from the RTC is prior to that clock time, it will force the system clock to that minimum time. This "minimum time" may be specified by the Meson build system, or it is read from the creation time of the NEWS file in the build environment.

The following logs show that the clock is getting advanced by systemd, as well as displaying the minimum clock value.

root@debian-vm:~# journalctl -b | grep time | grep systemd
Nov 03 17:16:43 debian-vm systemd[1]: System time before build time, advancing clock.

root@debian-vm:~# date --date="$(uptime -s)" +%s
1478193400

root@debian-vm:~# uptime -s
2016-11-03 17:16:40

You can see the systemd source code that checks for the minimum clock here

Related Question