diff options
author | Richard Cochran <richardcochran@gmail.com> | 2014-04-27 09:01:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-04-28 13:28:43 -0400 |
commit | d39a743511cdb80884b4b9cd506fe84b6b08e66e (patch) | |
tree | 708d00e333ca4096af001a5ad2b8dfc250f254ab /drivers/ptp | |
parent | 5a2b646ffe21e6014314b4d1df040e2553e39a3b (diff) |
ptp: validate the requested frequency adjustment.
PTP Hardware Clock drivers specify a maximum frequency adjustment that
their clocks can accommodate. Normally, user space programs will want to
respect the advertised limits. However, no kernel or driver code checks
that the dialed frequency offset is within the bounds, and out of range
values can lead to surprising results.
This patch fixes the issue by rejecting bad values.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ptp')
-rw-r--r-- | drivers/ptp/ptp_clock.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index e25d2bc898e5..296b0ec8744d 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c | |||
@@ -142,7 +142,10 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) | |||
142 | delta = ktime_to_ns(kt); | 142 | delta = ktime_to_ns(kt); |
143 | err = ops->adjtime(ops, delta); | 143 | err = ops->adjtime(ops, delta); |
144 | } else if (tx->modes & ADJ_FREQUENCY) { | 144 | } else if (tx->modes & ADJ_FREQUENCY) { |
145 | err = ops->adjfreq(ops, scaled_ppm_to_ppb(tx->freq)); | 145 | s32 ppb = scaled_ppm_to_ppb(tx->freq); |
146 | if (ppb > ops->max_adj || ppb < -ops->max_adj) | ||
147 | return -ERANGE; | ||
148 | err = ops->adjfreq(ops, ppb); | ||
146 | ptp->dialed_frequency = tx->freq; | 149 | ptp->dialed_frequency = tx->freq; |
147 | } else if (tx->modes == 0) { | 150 | } else if (tx->modes == 0) { |
148 | tx->freq = ptp->dialed_frequency; | 151 | tx->freq = ptp->dialed_frequency; |