port: Avoid calling freed servo after switching PHC.
In port_synchronize(), when the clock returned SERVO_UNLOCKED and
port_dispatch() triggered a switch of the PHC, the variable "s" would
point to a servo which was already freed and the following call of
servo_offset_threshold() would read invalid memory.
Don't save the servo before dispatching the port.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Fixes: 3f5f5653d7
("port: Add interval update mechanism.")
master
parent
f9e84e69bf
commit
e20d8228f9
6
port.c
6
port.c
|
@ -1137,7 +1137,6 @@ static void port_synchronize(struct port *p,
|
||||||
{
|
{
|
||||||
enum servo_state state, last_state;
|
enum servo_state state, last_state;
|
||||||
tmv_t t1, t1c, t2, c1, c2;
|
tmv_t t1, t1c, t2, c1, c2;
|
||||||
struct servo *s;
|
|
||||||
|
|
||||||
port_set_sync_rx_tmo(p);
|
port_set_sync_rx_tmo(p);
|
||||||
|
|
||||||
|
@ -1147,13 +1146,12 @@ static void port_synchronize(struct port *p,
|
||||||
c2 = correction_to_tmv(correction2);
|
c2 = correction_to_tmv(correction2);
|
||||||
t1c = tmv_add(t1, tmv_add(c1, c2));
|
t1c = tmv_add(t1, tmv_add(c1, c2));
|
||||||
|
|
||||||
s = clock_servo(p->clock);
|
|
||||||
last_state = clock_servo_state(p->clock);
|
last_state = clock_servo_state(p->clock);
|
||||||
state = clock_synchronize(p->clock, t2, t1c);
|
state = clock_synchronize(p->clock, t2, t1c);
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case SERVO_UNLOCKED:
|
case SERVO_UNLOCKED:
|
||||||
port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0);
|
port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0);
|
||||||
if (servo_offset_threshold(s) != 0 &&
|
if (servo_offset_threshold(clock_servo(p->clock)) != 0 &&
|
||||||
sync_interval != p->initialLogSyncInterval) {
|
sync_interval != p->initialLogSyncInterval) {
|
||||||
p->logPdelayReqInterval = p->logMinPdelayReqInterval;
|
p->logPdelayReqInterval = p->logMinPdelayReqInterval;
|
||||||
p->logSyncInterval = p->initialLogSyncInterval;
|
p->logSyncInterval = p->initialLogSyncInterval;
|
||||||
|
@ -1186,7 +1184,7 @@ static void port_synchronize(struct port *p,
|
||||||
* The most likely reason for this to happen is the
|
* The most likely reason for this to happen is the
|
||||||
* master daemon re-initialized due to some fault.
|
* master daemon re-initialized due to some fault.
|
||||||
*/
|
*/
|
||||||
servo_reset(s);
|
servo_reset(clock_servo(p->clock));
|
||||||
port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0);
|
port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue