lib: Solve race condition in Link State#21922
Conversation
When a consumer request a TED synchronisation by calling ls_request_sync(), producer send TED elements with SYNC message which are in turn parse by ls_msg2ted() function or individual ls_msg2vertex(), ls_msg2edge() or ls_msg2subnet() function. In all cases, ls_xxx_add() functions are called. However, in some race condition, TED is not empty and already contains the same element that is under synchronisation. TED is an RB_TREE_UNIQ structure. Thus, TED is not allowed duplicate entry. The problem occurs when ls_xxx_add() functions try to add a sync element while it already exist. This element is not inserted in the TED and allocated memory lost at the end of caller leaving memory leaks when daemon stop. This patch replace call to ls_xxx_add() functions by ls_xxx_update() functions when parsing SYNC message. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Greptile SummaryThis PR addresses a memory leak in the Link State TED (Traffic Engineering Database) synchronization path. When a consumer calls
Confidence Score: 4/5The change is a small, focused fix confined to three switch branches; the _update functions already existed and were used for UPDATE events, so their behaviour is well-proven. The ADD path still has the same underlying vulnerability but that is explicitly deferred to a follow-up PR. The three changed lines correctly swap in functions that already handle the duplicate-entry case, memory is freed or adopted properly in both the matching and non-matching branches, and the SYNC status override is intentional and harmless. The only gap is the identical vulnerability still present in the ADD branches, which the author calls out as a follow-up item. lib/link_state.c — specifically the LS_MSG_EVENT_ADD branches in ls_msg2vertex, ls_msg2edge, and ls_msg2subnet. Important Files Changed
Sequence DiagramsequenceDiagram
participant C as Consumer
participant P as Producer
participant TED as TED (RB-tree)
C->>P: ls_request_sync()
P->>C: LS_MSG_EVENT_SYNC (vertex/edge/subnet)
C->>C: ls_msg2vertex / ls_msg2edge / ls_msg2subnet
alt Element does NOT exist (normal path)
C->>TED: ls_xxx_update() calls ls_xxx_add()
TED-->>C: "new element inserted, status=SYNC"
else Element ALREADY EXISTS (race condition, fixed by this PR)
C->>TED: ls_xxx_update() finds existing entry
TED-->>C: existing element returned, payload freed or adopted
C->>TED: "set status=SYNC on existing element"
end
|
When a consumer request a TED synchronisation by calling ls_request_sync(), producer send TED elements with SYNC message which are in turn parse by ls_msg2ted() function or individual ls_msg2vertex(), ls_msg2edge() or ls_msg2subnet() function. In all cases, ls_xxx_add() functions are called. However, in some race condition, TED is not empty and already contains the same element that is under synchronisation. TED is an RB_TREE_UNIQ structure. Thus, TED is not allowed duplicate entry. The problem occurs when ls_xxx_add() functions try to add a sync element while it already exist. This element is not inserted in the TED and allocated memory lost at the end of caller leaving memory leaks when daemon stop.
This patch replace call to ls_xxx_add() functions by ls_xxx_update() functions when parsing SYNC message.
However, this patch is not solved the root cause which seems due to concurrent SYNC messages. Another PR will be proposed latter to solve the root cause.