{"id":"GHSA-q95x-7g78-rccv","aliases":["RUSTSEC-2026-0152"],"status":"published","title":"OneRingBuf has a Use After Free Vulnerability","description":"Affected versions of `oneringbuf` exposed the obsolete `IntoRef::into_ref` method through the public `IntoRef` trait. For heap-backed ring buffers, this method returned a `DroppableRef` handle.\n\n`DroppableRef` stored an owning raw pointer created from `Box::into_raw`. Its `Clone` implementation copied this raw pointer without incrementing the internal `alive_iters` counter. Internally, this clone pattern appears to rely on a fixed number of handles being created to match the initial `alive_iters` value. However, exposing `DroppableRef` through the public `IntoRef::TargetRef` associated type allows safe external code to create additional clones beyond that fixed count, breaking the lifetime protocol. `Drop` later dereferenced the pointer and could free the backing allocation with `Box::from_raw`.\n\nSafe code could call `IntoRef::into_ref` to obtain a `DroppableRef` and then clone it. Each clone pointed to the same allocation, but the internal `alive_iters` counter was not increased. As a result, one clone could free the allocation while another clone still existed. Dropping the remaining clone then accessed freed memory, causing a heap-use-after-free.\n\nThe issue was fixed in version 0.8.0 by removing the obsolete `into_ref` method.\n\n## Trigger\n\n```rust\nuse oneringbuf::{IntoRef, LocalHeapRB};\n\nfn main() {\n    let rb = LocalHeapRB::\u003cusize\u003e::from(vec![1, 2, 3]);\n\n    let r = \u003cLocalHeapRB\u003cusize\u003e as IntoRef\u003e::into_ref(rb);\n    let r2 = r.clone();\n    let r3 = r.clone();\n\n    drop(r);\n    drop(r2);\n    drop(r3); // AddressSanitizer: heap-use-after-free\n}\n```","severity":{"version":"4.0","score":6.3,"vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N","level":"medium","from":"ghsa"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-416"],"published":"2026-05-27T12:00:00Z","modified":"2026-08-04T09:30:04Z","fixes":[{"ecosystem":"crates.io","package":"oneringbuf","fixed_in":["0.8.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"crates.io","package":"oneringbuf","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.8.0"}]}]},{"source":"osv","ecosystem":"crates.io","package":"oneringbuf","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.8.0"}]}]},{"source":"osv","ecosystem":"crates.io","package":"oneringbuf","ranges":[{"type":"SEMVER","events":[{"introduced":"0.0.0-0"},{"fixed":"0.8.0"}]}]}],"references":[{"url":"https://github.com/skilvingr/rust-oneringbuf/commit/643a24b30914068416dff9021a069c12c865a316","tags":["web"]},{"url":"https://rustsec.org/advisories/RUSTSEC-2026-0152.html","tags":["web","advisory"]},{"url":"https://github.com/advisories/GHSA-q95x-7g78-rccv"},{"url":"https://github.com/Skilvingr/rust-oneringbuf","tags":["package"]},{"url":"https://crates.io/crates/oneringbuf","tags":["package"]}],"sources":{"ghsa":[{"id":"GHSA-q95x-7g78-rccv","title":"OneRingBuf has a Use After Free Vulnerability","description":"Affected versions of `oneringbuf` exposed the obsolete `IntoRef::into_ref` method through the public `IntoRef` trait. For heap-backed ring buffers, this method returned a `DroppableRef` handle.\n\n`DroppableRef` stored an owning raw pointer created from `Box::into_raw`. Its `Clone` implementation copied this raw pointer without incrementing the internal `alive_iters` counter. Internally, this clone pattern appears to rely on a fixed number of handles being created to match the initial `alive_iters` value. However, exposing `DroppableRef` through the public `IntoRef::TargetRef` associated type allows safe external code to create additional clones beyond that fixed count, breaking the lifetime protocol. `Drop` later dereferenced the pointer and could free the backing allocation with `Box::from_raw`.\n\nSafe code could call `IntoRef::into_ref` to obtain a `DroppableRef` and then clone it. Each clone pointed to the same allocation, but the internal `alive_iters` counter was not increased. As a result, one clone could free the allocation while another clone still existed. Dropping the remaining clone then accessed freed memory, causing a heap-use-after-free.\n\nThe issue was fixed in version 0.8.0 by removing the obsolete `into_ref` method.\n\n## Trigger\n\n```rust\nuse oneringbuf::{IntoRef, LocalHeapRB};\n\nfn main() {\n    let rb = LocalHeapRB::\u003cusize\u003e::from(vec![1, 2, 3]);\n\n    let r = \u003cLocalHeapRB\u003cusize\u003e as IntoRef\u003e::into_ref(rb);\n    let r2 = r.clone();\n    let r3 = r.clone();\n\n    drop(r);\n    drop(r2);\n    drop(r3); // AddressSanitizer: heap-use-after-free\n}\n```","status":"published","published":"2026-07-08T20:26:23Z","modified":"2026-07-08T20:26:24Z","cvss":[{"version":"4.0","score":6.3,"vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-416"],"updated_at":"2026-11-02T14:40:41.501474Z"}],"osv":[{"id":"GHSA-q95x-7g78-rccv","title":"OneRingBuf has a Use After Free Vulnerability","description":"Affected versions of `oneringbuf` exposed the obsolete `IntoRef::into_ref` method through the public `IntoRef` trait. For heap-backed ring buffers, this method returned a `DroppableRef` handle.\n\n`DroppableRef` stored an owning raw pointer created from `Box::into_raw`. Its `Clone` implementation copied this raw pointer without incrementing the internal `alive_iters` counter. Internally, this clone pattern appears to rely on a fixed number of handles being created to match the initial `alive_iters` value. However, exposing `DroppableRef` through the public `IntoRef::TargetRef` associated type allows safe external code to create additional clones beyond that fixed count, breaking the lifetime protocol. `Drop` later dereferenced the pointer and could free the backing allocation with `Box::from_raw`.\n\nSafe code could call `IntoRef::into_ref` to obtain a `DroppableRef` and then clone it. Each clone pointed to the same allocation, but the internal `alive_iters` counter was not increased. As a result, one clone could free the allocation while another clone still existed. Dropping the remaining clone then accessed freed memory, causing a heap-use-after-free.\n\nThe issue was fixed in version 0.8.0 by removing the obsolete `into_ref` method.\n\n## Trigger\n\n```rust\nuse oneringbuf::{IntoRef, LocalHeapRB};\n\nfn main() {\n    let rb = LocalHeapRB::\u003cusize\u003e::from(vec![1, 2, 3]);\n\n    let r = \u003cLocalHeapRB\u003cusize\u003e as IntoRef\u003e::into_ref(rb);\n    let r2 = r.clone();\n    let r3 = r.clone();\n\n    drop(r);\n    drop(r2);\n    drop(r3); // AddressSanitizer: heap-use-after-free\n}\n```","status":"published","published":"2026-07-08T20:26:23Z","modified":"2026-07-09T06:56:37.198846378Z","cvss":[{"version":"4.0","score":6.3,"vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-416"],"updated_at":"2026-11-02T15:46:54.40888Z"},{"id":"RUSTSEC-2026-0152","title":"Use-after-free","description":"Affected versions of `oneringbuf` exposed the obsolete `IntoRef::into_ref` method through the public `IntoRef` trait. For heap-backed ring buffers, this method returned a `DroppableRef` handle.\n\n`DroppableRef` stored an owning raw pointer created from `Box::into_raw`. Its `Clone` implementation copied this raw pointer without incrementing the internal `alive_iters` counter. Internally, this clone pattern appears to rely on a fixed number of handles being created to match the initial `alive_iters` value. However, exposing `DroppableRef` through the public `IntoRef::TargetRef` associated type allows safe external code to create additional clones beyond that fixed count, breaking the lifetime protocol. `Drop` later dereferenced the pointer and could free the backing allocation with `Box::from_raw`.\n\nSafe code could call `IntoRef::into_ref` to obtain a `DroppableRef` and then clone it. Each clone pointed to the same allocation, but the internal `alive_iters` counter was not increased. As a result, one clone could free the allocation while another clone still existed. Dropping the remaining clone then accessed freed memory, causing a heap-use-after-free.\n\nThe issue was fixed in version 0.8.0 by removing the obsolete `into_ref` method.\n\n## Trigger\n\n```rust\nuse oneringbuf::{IntoRef, LocalHeapRB};\n\nfn main() {\n    let rb = LocalHeapRB::\u003cusize\u003e::from(vec![1, 2, 3]);\n\n    let r = \u003cLocalHeapRB\u003cusize\u003e as IntoRef\u003e::into_ref(rb);\n    let r2 = r.clone();\n    let r3 = r.clone();\n\n    drop(r);\n    drop(r2);\n    drop(r3); // AddressSanitizer: heap-use-after-free\n}\n```","status":"published","published":"2026-05-27T12:00:00Z","modified":"2026-08-04T09:30:04.384886369Z","updated_at":"2026-11-02T15:53:40.430679Z"}]}}
