diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index d6f54ccaf93b..4111342d64f0 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -159,7 +160,18 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx) delta = ktime_to_ns(kt); err = ops->adjtime(ops, delta); } else if (tx->modes & ADJ_FREQUENCY) { - long ppb = scaled_ppm_to_ppb(tx->freq); + long ppb; + s64 tmp; + + /* + * scaled_ppm_to_ppb() multiplies (1 + freq) by 125 in s64; + * reject a ->freq large enough to overflow that, which would + * otherwise wrap the result back into the max_adj range. + */ + if (check_add_overflow((s64)tx->freq, (s64)1, &tmp) || + check_mul_overflow(tmp, (s64)125, &tmp)) + return -ERANGE; + ppb = scaled_ppm_to_ppb(tx->freq); if (ppb > ops->max_adj || ppb < -ops->max_adj) return -ERANGE; err = ops->adjfine(ops, tx->freq);