From d7bcdca7a9550ac7439f0aba5edfa9c3ae94d4df Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sat, 5 May 2012 12:48:48 +0200 Subject: [PATCH] Clamp maximum adjustment to numerical limit. On 32 bit platforms, a PHC driver might allow a larger adjustment than can fit into the 'long' type used in the clock_adjtime interface. This patch fixes the issue by using the smaller of the two maxima. Signed-off-by: Richard Cochran --- phc.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/phc.c b/phc.c index 16a61ef..de5eeb8 100644 --- a/phc.c +++ b/phc.c @@ -27,6 +27,15 @@ #include "phc.h" +/* + * On 32 bit platforms, the PHC driver's maximum adjustment (type + * 'int' in units of ppb) can overflow the timex.freq field (type + * 'long'). So in this case we clamp the maximum to the largest + * possible adjustment that fits into a 32 bit long. + */ +#define BITS_PER_LONG (sizeof(long)*8) +#define MAX_PPB_32 32767999 /* 2^31 - 1 / 65.536 */ + clockid_t phc_open(char *phc) { int fd = open(phc, O_RDWR); @@ -44,7 +53,7 @@ void phc_close(clockid_t clkid) int phc_max_adj(clockid_t clkid) { - int fd = CLOCKID_TO_FD(clkid); + int fd = CLOCKID_TO_FD(clkid), max; struct ptp_clock_caps caps; if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) { @@ -52,5 +61,10 @@ int phc_max_adj(clockid_t clkid) return 0; } - return caps.max_adj; + max = caps.max_adj; + + if (BITS_PER_LONG == 32 && max > MAX_PPB_32) + max = MAX_PPB_32; + + return max; }