Skip to content

Instantly share code, notes, and snippets.

@sebres
Last active August 22, 2022 13:54
Show Gist options
  • Save sebres/0bba158de5bb01736ac4da93fe7916d2 to your computer and use it in GitHub Desktop.
Save sebres/0bba158de5bb01736ac4da93fe7916d2 to your computer and use it in GitHub Desktop.
PoC-time-jumps.sh -- proof of concept to detect FPU/hardware related issues causing time jump in python (fail2ban/fail2ban#3187)
#! /bin/sh
printf '%s' '
#include <inttypes.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#define SEC_TO_NS (1000 * 1000 * 1000)
double
_Time_AsSecondsDouble(int64_t t)
{
/* volatile avoids optimization changing how numbers are rounded */
volatile double d;
if (t % SEC_TO_NS == 0) {
/* Divide using integers to avoid rounding issues on the integer part.
1e-9 cannot be stored exactly in IEEE 64-bit. */
t /= SEC_TO_NS;
d = (double)t;
}
else {
d = (double)t;
d /= 1e9;
}
return d;
}
int64_t
_Time_GetTime()
{
int64_t t;
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts)) {
printf("ERROR: clock_gettime fails\n");
exit(-1);
}
t = ts.tv_sec;
t *= SEC_TO_NS;
t += ts.tv_nsec;
return t;
}
int
main()
{
int64_t t, t0 = _Time_GetTime();
double d, d0 = _Time_AsSecondsDouble(t0);
printf("%"PRId64"\t%.3f \t ...\n", t0, d0);
while (1) {
usleep(500000);
t = _Time_GetTime();
d = _Time_AsSecondsDouble(t);
printf("%"PRId64"\t%.3f \t +%"PRId64"\t+%.3f\n", t, d, t - t0, d - d0);
if (t - t0 > SEC_TO_NS || t0 - t > SEC_TO_NS || d - d0 > 1 || d0 - d > 1) break;
t0 = t;
d0 = d;
}
return 0;
}
// ' > ./poc-time-jumps.c; gcc -O2 -Wall -Wextra ./poc-time-jumps.c -o ./poc-time-jumps && ./poc-time-jumps
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment