[ntp] Offset with system date might be greater than a signed long

If system date is completely out of sync with the reality, the resulting
offset might be too much for a signed long. For example, with a BIOS
date configured in 1921:

NTP 0xa068e6a8 sending request
NTP 0xa068e6a8 delta -1139207296 seconds

Co-authored-by: Sylvain Burette sylvain.burette@corp.ovh.com
Co-authored-by: Clement Sciascia clement.sciascia@corp.ovh.com
pull/455/head
Yannick Hemery 2021-09-03 17:39:29 +02:00
parent e09e1142a3
commit 7393b5a894
3 changed files with 20 additions and 8 deletions

View File

@ -44,7 +44,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*/
/** Current system clock offset */
signed long time_offset;
signed long long time_offset;
/** Days of week (for debugging) */
static const char *weekdays[] = {

View File

@ -50,7 +50,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/* Include all architecture-dependent time API headers */
#include <bits/time.h>
extern signed long time_offset;
extern signed long long time_offset;
/**
* Get current time in seconds (ignoring system clock offset)
@ -65,7 +65,7 @@ time_t time_now ( void );
* @v delta Clock adjustment, in seconds
*/
static inline __attribute__ (( always_inline )) void
time_adjust ( signed long delta ) {
time_adjust ( signed long long delta ) {
time_offset += delta;
}

View File

@ -90,6 +90,10 @@ static int ntp_request ( struct ntp_client *ntp ) {
hdr.transmit.seconds = htonl ( time ( NULL ) + NTP_EPOCH );
hdr.transmit.fraction = htonl ( NTP_FRACTION_MAGIC );
DBGC ( ntp, "NTP %p local time (epoch) %lld seconds "
"(when adding NTP_EPOCH 0x%08x)\n",
ntp, time ( NULL ), hdr.transmit.seconds );
/* Send request */
if ( ( rc = xfer_deliver_raw ( &ntp->xfer, &hdr,
sizeof ( hdr ) ) ) != 0 ) {
@ -113,7 +117,7 @@ static int ntp_deliver ( struct ntp_client *ntp, struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
struct ntp_header *hdr;
struct sockaddr_tcpip *st_src;
int32_t delta;
int64_t delta;
int rc;
/* Check source port */
@ -154,10 +158,18 @@ static int ntp_deliver ( struct ntp_client *ntp, struct io_buffer *iobuf,
goto close;
}
/* Calculate clock delta */
delta = ( ntohl ( hdr->receive.seconds ) -
ntohl ( hdr->originate.seconds ) );
DBGC ( ntp, "NTP %p delta %d seconds\n", ntp, delta );
int64_t receive = ntohl( hdr->receive.seconds );
int64_t originate = ntohl( hdr->originate.seconds );
int64_t receive_epoch = receive - NTP_EPOCH;
int64_t originate_epoch = originate - NTP_EPOCH;
DBGC ( ntp, "NTP %p answered 'receive' %lld (0x%08llx) and 'originate' %lld (0x%08llx)\n",
ntp, receive_epoch, receive_epoch, originate_epoch, originate_epoch );
/* Calculate clock delta on 64-bits signed integer */
delta = receive - originate;
DBGC ( ntp, "NTP %p delta %lld seconds (0x%016llx)\n", ntp, delta, delta );
/* Adjust system clock */
time_adjust ( delta );