clock: Safely remove event subscribers from list.

When updating and potentially removing event subscribers, the code uses
the simple list traversal macro.  As a result, the list will become
corrupted whenever a subscriber is removed.  This patch fixes the issue
by using the appropriate macro.

Fixes: 5104e3e56b ("Event subscribing")
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Reported-by: Michael Walle <michael@walle.cc>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
master
Richard Cochran 2020-03-06 11:01:31 -08:00
parent 25d4e4fbdd
commit 45aa981e4a
1 changed files with 4 additions and 5 deletions

View File

@ -145,9 +145,9 @@ static void remove_subscriber(struct clock_subscriber *s)
static void clock_update_subscription(struct clock *c, struct ptp_message *req, static void clock_update_subscription(struct clock *c, struct ptp_message *req,
uint8_t *bitmask, uint16_t duration) uint8_t *bitmask, uint16_t duration)
{ {
struct clock_subscriber *s; struct clock_subscriber *s, *tmp;
int i, remove = 1;
struct timespec now; struct timespec now;
int i, remove = 1;
for (i = 0; i < EVENT_BITMASK_CNT; i++) { for (i = 0; i < EVENT_BITMASK_CNT; i++) {
if (bitmask[i]) { if (bitmask[i]) {
@ -156,12 +156,11 @@ static void clock_update_subscription(struct clock *c, struct ptp_message *req,
} }
} }
LIST_FOREACH(s, &c->subscribers, list) { LIST_FOREACH_SAFE(s, &c->subscribers, list, tmp) {
if (pid_eq(&s->targetPortIdentity, if (pid_eq(&s->targetPortIdentity,
&req->header.sourcePortIdentity)) { &req->header.sourcePortIdentity)) {
/* Found, update the transport address and event
* mask. */
if (!remove) { if (!remove) {
/* Update transport address and event mask. */
s->addr = req->address; s->addr = req->address;
memcpy(s->events, bitmask, EVENT_BITMASK_CNT); memcpy(s->events, bitmask, EVENT_BITMASK_CNT);
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);