Dependingon what IDE and SDK you are using, time_t is implemented as different things. In Keil with nRF5 SDK time_t is implemented as an unsigned 32 bit int which will most likely be hit by the Y38 issue. As far as I can see typecasting this to a 64bit based type may cause code-compliancy issues with other functionalties depending on the time library. Since the nRF5 SDK is in maintenance mode, there are no guarantees that this will be fixed - for more details see this blog post.
Hi,
Unfortunally we do not support DFU/FOTA upgrades from nRF5 SDK to nRF Connect SDK. This thread from a few months ago is a good read as to why we don't support it, some reasons to migrate from nRF5 SDK to nRF Connect SDK, as well as the challenges that may come with trying to create a custom DFU method.
I believe the discussion in that thread answers this questions, and feel free to join in on that thread if you have any follow up questions to what is asked there. Additionally, please feel free to ask more questions here as well if your question is still unanswered!
Kind regards,
Andreas
Last November, I put up alistof a bunch of "magic numbers" including some years in which time/date stuff is likely to break. There's 2036 for the NTP era rollover, 2038 for time_t requiring 32 bits in January *and* another GPS week rollover in November.
Looking at the current year gives you a hint. It's 2021, but another way of looking at that is that we're 121 years past the year 1900. A fair number of things use(d) 1900 as an epoch, base year, or just an offset of sorts. Why? Well, they were probably invented in simpler times when the current year wasn't quite that far from 1900 at the time, and it would fit into fewer bits. Specifically, it'll fit into just seven bits... until 2028, that is.
Why would people do that? Assume they had limited bits to work with on the systems of the day. You need at least 11 bits to store a value in the neighborhood of our current years. Besides, at the time, 2028 probably looked like it was so far away that it'd never be a problem, because there's no way this stuff would still be use in by then, right?
So, if someone used 1900 as their base year, stored years relative to that, and then did it in just seven bits (or eight bits where one of them is a sign bit), it'll overflow in a little over six years. What happens then depends on which method was used, and whether it applies certain kinds of sanity checks.
Out of curiosity, I went looking for more info and did find a reference to this same problemthat might be useful if you're trying to keep your HP 3000 alive. You know, the things with the 300+ lb disk drives? (If you know, you know.)
Wikipedia does have 2028 in their epiclistof time formatting and storage bugs, naturally, but it only talks about systems from the '70s. It doesn't mention ISO 9660 at all - at the moment, that is. Perhaps someone in the know will update it and then this comment will be obsolete.
If you are responsible for a bit-constrained system that might be storing years this way, you owe it to everyone to go look and see what'll happen. Maybe try setting one forward to 2028-01-01 and see if it remains happy or if it decides to go party in the 18th century.
While I have your attention, for the younger set out there: as long as we're talking about bits and years, you aren't necessarily in the clear. You might've noticed that 11 bits will hold the whole year, as in 2021, with no offsetting needed. Perhaps you even designed a system that shaved things down to their minimum storage sizes based on this.
We discovered it back in the late 1990's with Windows NT. There was a bug in the BIOS in some Unisys PCs. Sometimes at midnight, the time would race ahead at a tremendous rate, but would stop with an error when a date in 2038 was reached. I forget the exact date, but sometime in February, I think.
You can relax, all time libraries should use a unsigned 32-bit variable for the time by now. That will take us to the year 2106. Hopefully long before that (I hope at least 30 or 40 years before that) a 64-bit variable will be used. That means we have still 48 years before we should start using a 64-bit variable. Perhaps 128-bit with 64-bit for the whole seconds and 64-bit for the fraction of seconds. Perhaps there will be a different time system by then that can use any date, also a date before 1970.
Fun fact: Did you know that the GCC compiler supports 64-bits variables, even for an Arduino Uno with a 8-bit microcontroller ? There are no libraries that support the uint64_t and int64_t, but the compiler can use it and do calculations with it.
It is possible that a binary compatibility of some data structures used by interacting
applications working on 32-bit or 64-bit Desktop and 16-bit or 32-bit Embedded platforms
will be broken.
- the application A on the 16-bit Embedded platform received and saved 8 bytes but has an
invalid value for the member 'tV' of the structure 'S' because 4 bytes are "lost".
The memory or a system stack is not corrupted, but the result of processing is unpredictable;
A change from the 32-bit 'time_t' to the 64-bit 'time_t' is NOT a small change. I still
remember the Y2K events when many companies were very busy with software changes and
verifications that all time related issues are taken into account.
Intel does not verify all solutions, including but not limited to any file transfers that may appear in this community. Accordingly, Intel disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade.
I quickly isolated this problem to something going wrong in mod_openssl_cert_is_active(). The logic itself looks sound. I added some debug prints to check the result codes from ASN1_TIME_cmp_time_t(), and indeed, this call seemed to return bogus values.
So I went and patched openssl to do some debug prints in ASN1_TIME_cmp_time_t() itself. Noticed that the value of the second argument inside the function was different from the value the argument had in the caller.
After adding a sizeof(time_t) print in both openssl and lighttpd the real problem was revealed. openssl was using 4-bytes for it, while lighttpd was using 8-bytes. This was obviously going to break big time.
So it seems that Yocto doesn't build the system with 64-bit time_t by default. I'm not sure who really is at fault here, but currently it looks like the lighttpd build system shouldn't unconditionally enable _TIME_BITS=64, but only if the rest of the system is also build like this.
Is this cause you problems beyond trace at startup? It should not, though I imagine that some startup scripts fail if a preflight check (lighttpd -f /etc/lighttpd/lighttpd.conf -tt) produces any trace on stderr, even if the preflight check exit value is 0 (success).
I did a quick review of lighttpd's code and did not find other places where lighttpd is passing time_t as an argument to an API from a different library, besides mod_gnutls and mod_wolfssl, also where lighttpd checks and warns if the certificate is not active (within range of notBefore and notAfter dates in the certificate). As I asked above, I wonder if this is an issue or not for lighttpd mod_gnutls on armv7hf. For mod_wolfssl, wolfssl wolfSSL_X509_cmp_time() takes (time_t *) as an argument and would have a similar issue to openssl ASN1_TIME_cmp_time_t()
The issue, as you have pointed out, is lighttpd using 64-bit time_t, but openssl or wolfssl using 32-bit time_t and exposing API interfaces using time_t. There are a number of OS distro-level migrations in progress, such as Debian and Gentoo that I linked above, and I am sure there are more.
I'm actually not sure. I guess we have been carrying around that error for some time now. The thing is that the hardware where the server runs on, just carries a self-signed certificate. If something didn't work properly then people have probably ignored it anyway.
Unix time[a] is a date and time representation widely used in computing. It measures time by the number of non-leap seconds that have elapsed since 00:00:00 UTC on 1st January 1970, the Unix epoch. In modern computing, values are sometimes stored with higher granularity, such as microseconds or nanoseconds.
Unix time is currently defined as the number of non-leap seconds which have passed since 00:00:00 UTC on Thursday, 1 January 1970, which is referred to as the Unix epoch.[3] Unix time is typically encoded as a signed integer.
Unix time is sometimes referred to as Epoch time. This can be misleading since Unix time is not the only time system based on an epoch and the Unix epoch is not the only epoch used by other time systems.[5]
Unix time differs from both Coordinated Universal Time (UTC) and International Atomic Time (TAI) in its handling of leap seconds. UTC includes leap seconds that adjust for the discrepancy between precise time, as measured by atomic clocks, and solar time, relating to the position of the earth in relation to the sun. International Atomic Time (TAI), in which every day is precisely 86400 seconds long, ignores solar time and gradually loses synchronization with the Earth's rotation at a rate of roughly one second per year. In Unix time, every day contains exactly 86400 seconds. Each leap second uses the timestamp of a second that immediately precedes or follows it.[3]
On a normal UTC day, which has a duration of 86400 seconds, the Unix time number changes in a continuous manner across midnight. For example, at the end of the day used in the examples above, the time representations progress as follows:
When a leap second occurs, the UTC day is not exactly 86400 seconds long and the Unix time number (which always increases by exactly 86400 each day) experiences a discontinuity. Leap seconds may be positive or negative. No negative leap second has ever been declared, but if one were to be, then at the end of a day with a negative leap second, the Unix time number would jump up by 1 to the start of the next day. During a positive leap second at the end of a day, which occurs about every year and a half on average, the Unix time number increases continuously into the next day during the leap second and then at the end of the leap second jumps back by 1 (returning to the start of the next day). For example, this is what happened on strictly conforming POSIX.1 systems at the end of 1998:
3a8082e126