Get real rand in `possiblyrandom` on supported platforms w/o feat
What changed, and why it matters
This commit fixes a bug in a small helper crate called `possiblyrandom` used by the Lightning Dev Kit. The crate was supposed to return real random bytes on normal operating systems, but due to a Cargo.toml misconfiguration it was silently returning zeros unless an explicit feature flag was turned on. Randomness is important for cryptographic operations; using predictable zeros could weaken security in places that expect random input. The patch makes the code actually call the system's random source on supported platforms.
Upgrade to a version of `rust-lightning` that includes this commit, and audit any downstream code that consumed `possiblyrandom` output before this fix to determine whether predictable zeros could have affected cryptographic material such as nonces, ephemeral keys, or channel identifiers. Review Cargo.toml cfg-to-feature mappings in other crates for similar mismatches.
Security signals we found
Cryptographic randomness source silently disabled, producing all-zero output
Conditional compilation mismatch between Cargo.toml target cfg and source feature cfg
Security-relevant helper crate (`possiblyrandom`) used by Lightning Dev Kit
Reported by external party (Project Loupe)
Evidence from the diff
The possiblyrandom crate provides getpossiblyrandom, which is documented as possibly returning random bytes and falling back to zeros. The original code only invoked getrandom when the getrandom Cargo feature was enabled. However, the crate’s Cargo.toml conditionally depended on getrandom via target cfg (excluding target_os = "unknown" and "none"), which does not automatically enable the corresponding feature = "getrandom" gate in the source. Consequently, on normal OS targets the dependency was present but the code path was disabled, causing the function to always fill the buffer with zeros. The patch changes the cfg guard to match the Cargo.toml target condition, so getrandom::getrandom(dest) is called on supported platforms regardless of whether the feature is explicitly enabled. The function now fills zeros first and then overwrites with random bytes if available, preserving the fall-back semantics.
Changed components
possiblyrandom/src/lib.rsgetpossiblyrandom functiongetrandom dependency integrationInspect captured patch +9 / −6
diff --git a/possiblyrandom/src/lib.rs b/possiblyrandom/src/lib.rs
index 9cbbad7..6ddbc6d 100644
--- a/possiblyrandom/src/lib.rs
+++ b/possiblyrandom/src/lib.rs
@@ -20,16 +20,19 @@
#![no_std]
-#[cfg(feature = "getrandom")]
+#[cfg(any(
+ feature = "getrandom",
+ not(any(target_os = "unknown", target_os = "none"))
+))]
extern crate getrandom;
/// Possibly fills `dest` with random data. May fill it with zeros.
#[inline]
pub fn getpossiblyrandom(dest: &mut [u8]) {
- #[cfg(feature = "getrandom")]
- if getrandom::getrandom(dest).is_err() {
- dest.fill(0);
- }
- #[cfg(not(feature = "getrandom"))]
dest.fill(0);
+ #[cfg(any(
+ feature = "getrandom",
+ not(any(target_os = "unknown", target_os = "none"))
+ ))]
+ let _ = getrandom::getrandom(dest);
}
Why this scored 61/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.