| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
…nter race and page-lifetime UAF
Introduce a third trailer state (page | UNMARKING) that aral_unmark_allocation
publishes before taking the page lock to decrement marked_elements, and clears
after. While the bit is visible, aral_freez_internal observes it in its claim
and spins until the final UNMARKED state is published, so:
- freez never sees an unmarked trailer with a stale marked_elements counter
(no spurious "marked > used" assertion under NETDATA_INTERNAL_CHECKS)
- the slot's refcount contribution stays in place across the trailer
transition, so the page cannot be destroyed under unmark's page_lock
(closes the UAF that surfaced in production as gorilla_writer_aral_unmark
SEGVs and aral_set_page_pointer dereferences of stale page pointers)
The freez hot path keeps its single atomic-exchange; the cold path (UNMARKING
observed) restores the bit and retries. Bit availability is guarded with a
_Static_assert against SYSTEM_REQUIRED_ALIGNMENT.
Add aral_unittest_concurrency() (8 scenarios) wired into aral_unittest under
NETDATA_INTERNAL_CHECKS and reachable via -W aralconcurrency:
1-3 clean unmark / unmark-on-unmarked / clean freez (with marked guard
on the same page)
4-6 forced races: freez wins claim, unmark wins trailer transition, and
the same with no grace period - each verifies counter consistency
7 last marked on page triggers list move
8 coordinated stress: 256 pointers, deterministic UNMARKING for every
slot, asserts the cold path was entered via a counter incremented in
aral_claim_page_pointer_after_element___wait_for_unmark
There was a problem hiding this comment.
No issues found across 3 files
Confidence score: 5/5
sequenceDiagram
participant C as Caller
participant AU as aral_unmark_allocation
participant AF as aral_freez_internal
participant T as Slot Trailer (Atomic Word)
participant P as ARAL Page (Counters & Lock)
Note over AU, AF: Concurrent access to the same allocation slot
rect rgb(240, 245, 255)
Note right of AU: UNMARKING Phase
AU->>T: NEW: atomic_compare_exchange(MARKED -> UNMARKING)
Note over T: State: UNMARKING (Stays in place to keep Page alive)
end
rect rgb(255, 245, 240)
Note right of AF: FREEZ (Claim) Phase
AF->>T: CHANGED: atomic_exchange(0)
T-->>AF: Returns UNMARKING
alt UNMARKING Observed (Cold Path)
AF->>T: NEW: restore UNMARKING via CAS(0, UNMARKING)
AF->>AF: tinysleep() / yield
end
end
rect rgb(240, 245, 255)
Note right of AU: Counter Update Phase
AU->>P: aral_page_lock()
AU->>P: CHANGED: decrement page->marked_elements
alt marked_elements == 0
AU->>P: Move page to appropriate ARAL list
end
AU->>T: NEW: atomic_store(UNMARKED)
AU->>P: aral_page_unlock()
end
rect rgb(255, 245, 240)
Note right of AF: Retry Phase
AF->>T: atomic_exchange(0)
T-->>AF: Returns UNMARKED
AF->>P: aral_page_lock()
AF->>P: decrement page->used_elements
Note over P: Counter Consistency: marked_elements <= used_elements
AF->>P: aral_page_unlock()
AF-->>C: Slot freed successfully
end
Sorry, something went wrong.
There was a problem hiding this comment.
This PR hardens ARAL’s unmark/freez concurrency by introducing a third trailer state (UNMARKING) to prevent counter invariants from being observed in an inconsistent state and to avoid page lifetime/UAF hazards during the trailer transition. It also adds a dedicated concurrency-focused unit test suite and exposes it via a new daemon CLI test option.
Changes:
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/libnetdata/aral/aral.h | Declares the new aral_unittest_concurrency() entry point under NETDATA_INTERNAL_CHECKS. |
| src/libnetdata/aral/aral.c | Implements the UNMARKING trailer state machine, updates unmark/freez logic, and adds the new concurrency unit tests + deterministic race hook. |
| src/daemon/main.c | Adds -W aralconcurrency to run the new ARAL concurrency unit tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
There was a problem hiding this comment.
Fixes a race between aral_unmark_allocation() and aral_freez_internal() by introducing an UNMARKING trailer state, ensuring page counters and page lifetime remain consistent during the unmark/freez transition. Adds deterministic concurrency tests for the new unmark/freez state machine and wires them into the daemon unittest CLI option.
Changes:
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/libnetdata/aral/aral.h | Exposes the new concurrency unittest API (guarded by NETDATA_INTERNAL_CHECKS). |
| src/libnetdata/aral/aral.c | Implements the UNMARKING trailer protocol, updates free/unmark interactions, and adds deterministic concurrency tests. |
| src/daemon/main.c | Adds CLI hook (-W aralconcurrency) to run the new ARAL concurrency tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
There was a problem hiding this comment.
Fixes a concurrency bug in ARAL’s per-slot trailer protocol by introducing an UNMARKING intermediate trailer state to serialize aral_unmark_allocation() vs aral_freez_internal(), preventing counter inconsistencies and page lifetime UAFs; adds deterministic concurrency tests and a CLI entry point to run them.
Changes:
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/libnetdata/aral/aral.h | Exposes aral_unittest_concurrency() under NETDATA_INTERNAL_CHECKS and adjusts preprocessor structure around unittest entry points. |
| src/libnetdata/aral/aral.c | Implements the UNMARKING trailer state machine, updates unmark/freez synchronization, and adds deterministic concurrency unit tests. |
| src/daemon/main.c | Adds -W aralconcurrency CLI option to run the new ARAL concurrency tests (guarded by NETDATA_INTERNAL_CHECKS). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
There was a problem hiding this comment.
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
There was a problem hiding this comment.
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
There was a problem hiding this comment.
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
There was a problem hiding this comment.
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
|
@cubic-dev-ai review this PR |
Sorry, something went wrong.
@stelfrag I have started the AI code review. It will take a few minutes to complete. |
Sorry, something went wrong.
|
Sorry, something went wrong.
There was a problem hiding this comment.
Tested during few hours on Debian 13, and everything worked as expected. LGTM!
Sorry, something went wrong.
* aral: serialize unmark/freez via UNMARKING trailer state, prevent counter race and page-lifetime UAF
Introduce a third trailer state (page | UNMARKING) that aral_unmark_allocation
publishes before taking the page lock to decrement marked_elements, and clears
after. While the bit is visible, aral_freez_internal observes it in its claim
and spins until the final UNMARKED state is published, so:
- freez never sees an unmarked trailer with a stale marked_elements counter
(no spurious "marked > used" assertion under NETDATA_INTERNAL_CHECKS)
- the slot's refcount contribution stays in place across the trailer
transition, so the page cannot be destroyed under unmark's page_lock
(closes the UAF that surfaced in production as gorilla_writer_aral_unmark
SEGVs and aral_set_page_pointer dereferences of stale page pointers)
The freez hot path keeps its single atomic-exchange; the cold path (UNMARKING
observed) restores the bit and retries. Bit availability is guarded with a
_Static_assert against SYSTEM_REQUIRED_ALIGNMENT.
Add aral_unittest_concurrency() (8 scenarios) wired into aral_unittest under
NETDATA_INTERNAL_CHECKS and reachable via -W aralconcurrency:
1-3 clean unmark / unmark-on-unmarked / clean freez (with marked guard
on the same page)
4-6 forced races: freez wins claim, unmark wins trailer transition, and
the same with no grace period - each verifies counter consistency
7 last marked on page triggers list move
8 coordinated stress: 256 pointers, deterministic UNMARKING for every
slot, asserts the cold path was entered via a counter incremented in
aral_claim_page_pointer_after_element___wait_for_unmark
* Address review comments
* Address review comments (2)
* Address review comments (3)
* Address review comments (4)
* Update src/libnetdata/aral/aral.c
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Address review comments (5)
* Address review comments (6)
* Address review comments (7)
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
(cherry picked from commit e8caf80)
| Back | FazBrowse Home | New Git URL |
Summary
Introduce a third trailer state (page | UNMARKING) that aral_unmark_allocation publishes before taking the page lock to decrement marked_elements, and clears after. While the bit is visible, aral_freez_internal observes it in its claim and spins until the final UNMARKED state is published, so:
freez never sees an unmarked trailer with a stale marked_elements counter (no spurious "marked > used" assertion under NETDATA_INTERNAL_CHECKS)
the slot's refcount contribution stays in place across the trailer transition, so the page cannot be destroyed under unmark's page_lock (closes the UAF that surfaced in production as gorilla_writer_aral_unmark SEGVs and aral_set_page_pointer dereferences of stale page pointers)
The freez hot path keeps its single atomic-exchange; the cold path (UNMARKING observed) restores the bit and retries. Bit availability is guarded with a _Static_assert against SYSTEM_REQUIRED_ALIGNMENT.
Add aral_unittest_concurrency() (8 scenarios) under NETDATA_INTERNAL_CHECKS and reachable via -W aralconcurrency:
Cases:
Summary by cubic
Serialize ARAL unmark/freez with a new UNMARKING trailer state to close the race that caused counter skew and page‑lifetime UAFs. Free path stays fast; adds deterministic concurrency tests and a CLI flag to run them.
Bug Fixes
New Features
Written for commit 0e7d02e. Summary will update on new commits.