mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
Remove Servo's wrapper around rand (#39979)
This wrapper was added in order to eliminate the number of file descriptors used accessing `/dev/urandom`, but these days `osrandom` and by proxy `rand` will try to use `getrandom` on Linux and similar system APIs on other platforms [^1]. This is a trial balloon for removing the wrapper, since almost all modern Linux systems have `getrandom` (available since Linux 3.17). [^1]: https://docs.rs/getrandom/0.3.4/getrandom/#supported-targets Testing: Should not change observable behavior (only in random ways), so should be covered by WPT tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
34
Cargo.lock
generated
34
Cargo.lock
generated
@@ -936,8 +936,8 @@ dependencies = [
|
||||
"embedder_traits",
|
||||
"ipc-channel",
|
||||
"log",
|
||||
"rand 0.9.2",
|
||||
"servo_config",
|
||||
"servo_rand",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
@@ -1590,12 +1590,12 @@ dependencies = [
|
||||
"parking_lot",
|
||||
"profile",
|
||||
"profile_traits",
|
||||
"rand 0.9.2",
|
||||
"rustc-hash 2.1.1",
|
||||
"script_traits",
|
||||
"serde",
|
||||
"servo-tracing",
|
||||
"servo_config",
|
||||
"servo_rand",
|
||||
"servo_url",
|
||||
"storage_traits",
|
||||
"stylo",
|
||||
@@ -2047,11 +2047,11 @@ dependencies = [
|
||||
"log",
|
||||
"net",
|
||||
"net_traits",
|
||||
"rand 0.9.2",
|
||||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"servo_config",
|
||||
"servo_rand",
|
||||
"servo_url",
|
||||
"uuid",
|
||||
]
|
||||
@@ -5569,12 +5569,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"pixels",
|
||||
"profile_traits",
|
||||
"rand 0.9.2",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"servo_arc",
|
||||
"servo_malloc_size_of",
|
||||
"servo_rand",
|
||||
"servo_url",
|
||||
"url",
|
||||
"uuid",
|
||||
@@ -6860,15 +6860,6 @@ dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fac4373cd91b4f55722c553fb0f286edbb81ef3ff6eec7b99d1898a4110a0b28"
|
||||
dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "range"
|
||||
version = "0.0.1"
|
||||
@@ -7330,6 +7321,7 @@ dependencies = [
|
||||
"phf",
|
||||
"pixels",
|
||||
"profile_traits",
|
||||
"rand 0.9.2",
|
||||
"range",
|
||||
"regex",
|
||||
"rustc-hash 2.1.1",
|
||||
@@ -7343,7 +7335,6 @@ dependencies = [
|
||||
"servo_config",
|
||||
"servo_geometry",
|
||||
"servo_malloc_size_of",
|
||||
"servo_rand",
|
||||
"servo_url",
|
||||
"smallvec",
|
||||
"storage_traits",
|
||||
@@ -7922,29 +7913,16 @@ dependencies = [
|
||||
"wr_malloc_size_of",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "servo_rand"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"log",
|
||||
"malloc_size_of_derive",
|
||||
"rand 0.8.5",
|
||||
"rand_core 0.6.4",
|
||||
"rand_isaac",
|
||||
"servo_malloc_size_of",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "servo_url"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"encoding_rs",
|
||||
"malloc_size_of_derive",
|
||||
"rand 0.9.2",
|
||||
"serde",
|
||||
"servo_arc",
|
||||
"servo_malloc_size_of",
|
||||
"servo_rand",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
@@ -115,9 +115,7 @@ percent-encoding = "2.3"
|
||||
proc-macro2 = "1"
|
||||
profile_traits = { path = "components/shared/profile" }
|
||||
quote = "1"
|
||||
rand = "0.8"
|
||||
rand_core = "0.6"
|
||||
rand_isaac = "0.3"
|
||||
rand = "0.9"
|
||||
raw-window-handle = "0.6"
|
||||
rayon = "1"
|
||||
read-fonts = "0.33.1"
|
||||
|
||||
@@ -19,8 +19,8 @@ blurmock = { version = "0.1.2", optional = true }
|
||||
embedder_traits = { workspace = true }
|
||||
ipc-channel = { workspace = true }
|
||||
log = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
servo_config = { path = "../config" }
|
||||
servo_rand = { path = "../rand" }
|
||||
uuid = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
|
||||
@@ -34,8 +34,8 @@ use bluetooth_traits::{
|
||||
use embedder_traits::{EmbedderMsg, EmbedderProxy};
|
||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||
use log::warn;
|
||||
use rand::{self, Rng};
|
||||
use servo_config::pref;
|
||||
use servo_rand::{self, Rng};
|
||||
|
||||
use crate::bluetooth::{
|
||||
BluetoothAdapter, BluetoothDevice, BluetoothGATTCharacteristic, BluetoothGATTDescriptor,
|
||||
@@ -430,9 +430,9 @@ impl BluetoothManager {
|
||||
|
||||
fn generate_device_id(&mut self) -> String {
|
||||
let mut device_id;
|
||||
let mut rng = servo_rand::thread_rng();
|
||||
let mut rng = rand::rng();
|
||||
loop {
|
||||
device_id = rng.r#gen::<u32>().to_string();
|
||||
device_id = rng.random::<u32>().to_string();
|
||||
if !self.cached_devices.contains_key(&device_id) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -49,12 +49,12 @@ net_traits = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
profile = { path = "../profile" }
|
||||
profile_traits = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
script_traits = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
servo-tracing = { workspace = true }
|
||||
servo_config = { path = "../config" }
|
||||
servo_rand = { path = "../rand" }
|
||||
servo_url = { path = "../url" }
|
||||
storage_traits = { workspace = true }
|
||||
stylo = { workspace = true }
|
||||
|
||||
@@ -158,6 +158,9 @@ use net_traits::{
|
||||
};
|
||||
use profile_traits::mem::ProfilerMsg;
|
||||
use profile_traits::{mem, time};
|
||||
use rand::rngs::SmallRng;
|
||||
use rand::seq::IndexedRandom;
|
||||
use rand::{Rng, SeedableRng};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use script_traits::{
|
||||
ConstellationInputEvent, DiscardBrowsingContext, DocumentActivity, ProgressiveWebMetricType,
|
||||
@@ -166,7 +169,6 @@ use script_traits::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use servo_config::prefs::{self, PrefValue};
|
||||
use servo_config::{opts, pref};
|
||||
use servo_rand::{Rng, ServoRng, SliceRandom, random};
|
||||
use servo_url::{Host, ImmutableOrigin, ServoUrl};
|
||||
use storage_traits::StorageThreads;
|
||||
use storage_traits::webstorage_thread::{StorageType, WebStorageThreadMsg};
|
||||
@@ -449,7 +451,7 @@ pub struct Constellation<STF, SWF> {
|
||||
|
||||
/// The random number generator and probability for closing pipelines.
|
||||
/// This is for testing the hardening of the constellation.
|
||||
random_pipeline_closure: Option<(ServoRng, f32)>,
|
||||
random_pipeline_closure: Option<(SmallRng, f32)>,
|
||||
|
||||
/// Phantom data that keeps the Rust type system happy.
|
||||
phantom: PhantomData<(STF, SWF)>,
|
||||
@@ -733,12 +735,12 @@ where
|
||||
webrender_wgpu,
|
||||
shutting_down: false,
|
||||
handled_warnings: VecDeque::new(),
|
||||
random_pipeline_closure: random_pipeline_closure_probability.map(|prob| {
|
||||
let seed = random_pipeline_closure_seed.unwrap_or_else(random);
|
||||
let rng = ServoRng::new_manually_reseeded(seed as u64);
|
||||
warn!("Randomly closing pipelines.");
|
||||
info!("Using seed {} for random pipeline closure.", seed);
|
||||
(rng, prob)
|
||||
random_pipeline_closure: random_pipeline_closure_probability.map(|probability| {
|
||||
let rng = random_pipeline_closure_seed
|
||||
.map(|seed| SmallRng::seed_from_u64(seed as u64))
|
||||
.unwrap_or_else(SmallRng::from_os_rng);
|
||||
warn!("Randomly closing pipelines using seed {random_pipeline_closure_seed:?}.");
|
||||
(rng, probability)
|
||||
}),
|
||||
webgl_threads: state.webgl_threads,
|
||||
webxr_registry: state.webxr_registry,
|
||||
@@ -5600,7 +5602,7 @@ where
|
||||
fn maybe_close_random_pipeline(&mut self) {
|
||||
match self.random_pipeline_closure {
|
||||
Some((ref mut rng, probability)) => {
|
||||
if probability <= rng.r#gen::<f32>() {
|
||||
if probability <= rng.random::<f32>() {
|
||||
return;
|
||||
}
|
||||
},
|
||||
@@ -5616,7 +5618,7 @@ where
|
||||
.pending_changes
|
||||
.iter()
|
||||
.any(|change| change.new_pipeline_id == pipeline.id) &&
|
||||
probability <= rng.r#gen::<f32>()
|
||||
probability <= rng.random::<f32>()
|
||||
{
|
||||
// We tend not to close pending pipelines, as that almost always
|
||||
// results in pipelines being closed early in their lifecycle,
|
||||
|
||||
@@ -24,11 +24,11 @@ ipc-channel = { workspace = true }
|
||||
log = { workspace = true }
|
||||
net = { path = "../net" }
|
||||
net_traits = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
servo_config = { path = "../config" }
|
||||
servo_rand = { path = "../rand" }
|
||||
servo_url = { path = "../url" }
|
||||
uuid = { workspace = true }
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@ use devtools_traits::{
|
||||
use embedder_traits::{AllowOrDeny, EmbedderMsg, EmbedderProxy};
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use log::{trace, warn};
|
||||
use rand::{RngCore, rng};
|
||||
use resource::{ResourceArrayType, ResourceAvailable};
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::Serialize;
|
||||
use servo_rand::RngCore;
|
||||
|
||||
use crate::actor::{Actor, ActorRegistry};
|
||||
use crate::actors::browsing_context::BrowsingContextActor;
|
||||
@@ -142,7 +142,7 @@ impl DevtoolsInstance {
|
||||
|
||||
// A token shared with the embedder to bypass permission prompt.
|
||||
let port = if bound.is_some() { Ok(port) } else { Err(()) };
|
||||
let token = format!("{:X}", servo_rand::ServoRng::default().next_u32());
|
||||
let token = format!("{:X}", rng().next_u32());
|
||||
embedder.send(EmbedderMsg::OnDevtoolsStarted(port, token.clone()));
|
||||
|
||||
let listener = match bound {
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
[package]
|
||||
name = "servo_rand"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lib]
|
||||
name = "servo_rand"
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
log = { workspace = true }
|
||||
malloc_size_of = { workspace = true }
|
||||
malloc_size_of_derive = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
rand_core = { workspace = true }
|
||||
rand_isaac = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
@@ -1,197 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use log::trace;
|
||||
use malloc_size_of_derive::MallocSizeOf;
|
||||
/// A random number generator which shares one instance of an `OsRng`.
|
||||
///
|
||||
/// A problem with `OsRng`, which is inherited by `StdRng` and so
|
||||
/// `ThreadRng`, is that it reads from `/dev/random`, and so consumes
|
||||
/// a file descriptor. For multi-threaded applications like Servo,
|
||||
/// it is easy to exhaust the supply of file descriptors this way.
|
||||
///
|
||||
/// This crate fixes that, by only using one `OsRng`, which is just
|
||||
/// used to seed and re-seed an `ServoRng`.
|
||||
use rand::distributions::{Distribution, Standard};
|
||||
use rand::rngs::OsRng;
|
||||
use rand::rngs::adapter::ReseedingRng;
|
||||
pub use rand::seq::SliceRandom;
|
||||
pub use rand::{Rng, RngCore, SeedableRng};
|
||||
use rand_isaac::isaac::IsaacCore;
|
||||
use uuid::{Builder, Uuid};
|
||||
|
||||
// The shared RNG which may hold on to a file descriptor
|
||||
static OS_RNG: Mutex<OsRng> = Mutex::new(OsRng);
|
||||
|
||||
// Generate 32K of data between reseedings
|
||||
const RESEED_THRESHOLD: u64 = 32_768;
|
||||
|
||||
// An in-memory RNG that only uses the shared file descriptor for seeding and reseeding.
|
||||
#[derive(MallocSizeOf)]
|
||||
pub struct ServoRng {
|
||||
#[ignore_malloc_size_of = "Defined in rand"]
|
||||
rng: ReseedingRng<IsaacCore, ServoReseeder>,
|
||||
}
|
||||
|
||||
impl RngCore for ServoRng {
|
||||
#[inline]
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
self.rng.next_u32()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
self.rng.next_u64()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fill_bytes(&mut self, bytes: &mut [u8]) {
|
||||
self.rng.fill_bytes(bytes)
|
||||
}
|
||||
|
||||
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> std::result::Result<(), rand_core::Error> {
|
||||
self.rng.try_fill_bytes(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Seed([u8; 32]);
|
||||
|
||||
impl AsMut<[u8]> for Seed {
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl SeedableRng for ServoRng {
|
||||
type Seed = Seed;
|
||||
|
||||
// This function is used in the reseeding process of rand hence why the RESEED_THRESHOLD is
|
||||
// used.
|
||||
fn from_seed(seed: Seed) -> ServoRng {
|
||||
trace!("Creating a new ServoRng.");
|
||||
let isaac_rng = IsaacCore::from_seed(seed.0);
|
||||
let reseeding_rng = ReseedingRng::new(isaac_rng, RESEED_THRESHOLD, ServoReseeder);
|
||||
ServoRng { rng: reseeding_rng }
|
||||
}
|
||||
}
|
||||
|
||||
impl ServoRng {
|
||||
/// Create a manually-reseeding instance of `ServoRng`.
|
||||
///
|
||||
/// Note that this RNG does not reseed itself, so care is needed to reseed the RNG
|
||||
/// is required to be cryptographically sound.
|
||||
pub fn new_manually_reseeded(seed: u64) -> ServoRng {
|
||||
trace!("Creating a new manually-reseeded ServoRng.");
|
||||
let isaac_rng = IsaacCore::seed_from_u64(seed);
|
||||
let reseeding_rng = ReseedingRng::new(isaac_rng, 0, ServoReseeder);
|
||||
ServoRng { rng: reseeding_rng }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ServoRng {
|
||||
/// Create an auto-reseeding instance of `ServoRng`.
|
||||
///
|
||||
/// This uses the shared `OsRng`, so avoids consuming
|
||||
/// a file descriptor.
|
||||
fn default() -> Self {
|
||||
trace!("Creating new ServoRng.");
|
||||
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
|
||||
let isaac_rng = IsaacCore::from_rng(&mut *os_rng).unwrap();
|
||||
let reseeding_rng = ReseedingRng::new(isaac_rng, RESEED_THRESHOLD, ServoReseeder);
|
||||
ServoRng { rng: reseeding_rng }
|
||||
}
|
||||
}
|
||||
|
||||
// The reseeder for the in-memory RNG.
|
||||
struct ServoReseeder;
|
||||
|
||||
impl RngCore for ServoReseeder {
|
||||
#[inline]
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
|
||||
os_rng.next_u32()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
|
||||
os_rng.next_u64()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fill_bytes(&mut self, bytes: &mut [u8]) {
|
||||
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
|
||||
os_rng.fill_bytes(bytes)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> std::result::Result<(), rand_core::Error> {
|
||||
let mut os_rng = OS_RNG.lock().expect("Poisoned lock.");
|
||||
os_rng.try_fill_bytes(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ServoReseeder {
|
||||
fn default() -> ServoReseeder {
|
||||
ServoReseeder
|
||||
}
|
||||
}
|
||||
|
||||
// A thread-local RNG, designed as a drop-in replacement for rand::ThreadRng.
|
||||
#[derive(Clone)]
|
||||
pub struct ServoThreadRng {
|
||||
rng: Rc<RefCell<ServoRng>>,
|
||||
}
|
||||
|
||||
// A thread-local RNG, designed as a drop-in replacement for rand::thread_rng.
|
||||
pub fn thread_rng() -> ServoThreadRng {
|
||||
SERVO_THREAD_RNG.with(|t| t.clone())
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static SERVO_THREAD_RNG: ServoThreadRng = ServoThreadRng { rng: Rc::new(RefCell::new(ServoRng::default())) };
|
||||
}
|
||||
|
||||
impl RngCore for ServoThreadRng {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
self.rng.borrow_mut().next_u32()
|
||||
}
|
||||
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
self.rng.borrow_mut().next_u64()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fill_bytes(&mut self, bytes: &mut [u8]) {
|
||||
self.rng.borrow_mut().fill_bytes(bytes)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> std::result::Result<(), rand_core::Error> {
|
||||
(self.rng.borrow_mut()).try_fill_bytes(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
// Generates a random value using the thread-local random number generator.
|
||||
// A drop-in replacement for rand::random.
|
||||
#[inline]
|
||||
pub fn random<T>() -> T
|
||||
where
|
||||
Standard: Distribution<T>,
|
||||
{
|
||||
thread_rng().r#gen()
|
||||
}
|
||||
|
||||
// TODO(eijebong): Replace calls to this by random once `uuid::Uuid` implements `rand::Rand` again.
|
||||
#[inline]
|
||||
pub fn random_uuid() -> Uuid {
|
||||
let mut bytes = [0; 16];
|
||||
thread_rng().fill_bytes(&mut bytes);
|
||||
Builder::from_random_bytes(bytes).into_uuid()
|
||||
}
|
||||
@@ -100,6 +100,7 @@ percent-encoding = { workspace = true }
|
||||
phf = "0.11"
|
||||
pixels = { path = "../pixels" }
|
||||
profile_traits = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
range = { path = "../range" }
|
||||
regex = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
@@ -112,7 +113,6 @@ servo-media = { workspace = true }
|
||||
servo_arc = { workspace = true }
|
||||
servo_config = { path = "../config" }
|
||||
servo_geometry = { path = "../geometry" }
|
||||
servo_rand = { path = "../rand" }
|
||||
servo_url = { path = "../url" }
|
||||
smallvec = { workspace = true }
|
||||
storage_traits = { workspace = true }
|
||||
|
||||
@@ -6,10 +6,10 @@ use dom_struct::dom_struct;
|
||||
use js::jsapi::{JSObject, Type};
|
||||
use js::rust::CustomAutoRooterGuard;
|
||||
use js::typedarray::{ArrayBufferView, ArrayBufferViewU8, TypedArray};
|
||||
use servo_rand::{RngCore, ServoRng};
|
||||
use rand::TryRngCore;
|
||||
use rand::rngs::OsRng;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::CryptoBinding::CryptoMethods;
|
||||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
||||
@@ -23,8 +23,6 @@ use crate::script_runtime::{CanGc, JSContext};
|
||||
#[dom_struct]
|
||||
pub(crate) struct Crypto {
|
||||
reflector_: Reflector,
|
||||
#[no_trace]
|
||||
rng: DomRefCell<ServoRng>,
|
||||
subtle: MutNullableDom<SubtleCrypto>,
|
||||
}
|
||||
|
||||
@@ -32,7 +30,6 @@ impl Crypto {
|
||||
fn new_inherited() -> Crypto {
|
||||
Crypto {
|
||||
reflector_: Reflector::new(),
|
||||
rng: DomRefCell::new(ServoRng::default()),
|
||||
subtle: MutNullableDom::default(),
|
||||
}
|
||||
}
|
||||
@@ -68,7 +65,11 @@ impl CryptoMethods<crate::DomTypeHolder> for Crypto {
|
||||
requested: None,
|
||||
});
|
||||
}
|
||||
self.rng.borrow_mut().fill_bytes(data);
|
||||
|
||||
if OsRng.try_fill_bytes(data).is_err() {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
|
||||
let underlying_object = unsafe { input.underlying_object() };
|
||||
TypedArray::<ArrayBufferViewU8, *mut JSObject>::from(*underlying_object)
|
||||
.map_err(|_| Error::JSFailed)
|
||||
|
||||
@@ -16,8 +16,8 @@ use js::rust::HandleObject;
|
||||
use mime::{self, Mime};
|
||||
use net_traits::http_percent_encode;
|
||||
use net_traits::request::Referrer;
|
||||
use rand::random;
|
||||
use rustc_hash::FxBuildHasher;
|
||||
use servo_rand::random;
|
||||
use style::attr::AttrValue;
|
||||
use style::str::split_html_space_chars;
|
||||
use stylo_atoms::Atom;
|
||||
|
||||
@@ -19,10 +19,8 @@ use js::jsval::{ObjectValue, UndefinedValue};
|
||||
use js::rust::wrappers::JS_ParseJSON;
|
||||
use js::rust::{HandleValue, MutableHandleValue};
|
||||
use js::typedarray::ArrayBufferU8;
|
||||
use servo_rand::ServoRng;
|
||||
|
||||
use crate::dom::bindings::buffer_source::create_buffer_source;
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{
|
||||
CryptoKeyMethods, KeyType, KeyUsage,
|
||||
};
|
||||
@@ -112,15 +110,12 @@ enum Operation {
|
||||
#[dom_struct]
|
||||
pub(crate) struct SubtleCrypto {
|
||||
reflector_: Reflector,
|
||||
#[no_trace]
|
||||
rng: DomRefCell<ServoRng>,
|
||||
}
|
||||
|
||||
impl SubtleCrypto {
|
||||
fn new_inherited() -> SubtleCrypto {
|
||||
SubtleCrypto {
|
||||
reflector_: Reflector::new(),
|
||||
rng: DomRefCell::new(ServoRng::default()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,7 +704,6 @@ impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
|
||||
&subtle.global(),
|
||||
extractable,
|
||||
key_usages,
|
||||
&subtle.rng,
|
||||
CanGc::note(),
|
||||
) {
|
||||
Ok(result) => result,
|
||||
@@ -2540,51 +2534,30 @@ impl NormalizedAlgorithm {
|
||||
global: &GlobalScope,
|
||||
extractable: bool,
|
||||
usages: Vec<KeyUsage>,
|
||||
rng: &DomRefCell<ServoRng>,
|
||||
can_gc: CanGc,
|
||||
) -> Result<CryptoKeyOrCryptoKeyPair, Error> {
|
||||
match self {
|
||||
NormalizedAlgorithm::AesKeyGenParams(algo) => match algo.name.as_str() {
|
||||
ALG_AES_CTR => aes_operation::generate_key_aes_ctr(
|
||||
global,
|
||||
algo,
|
||||
extractable,
|
||||
usages,
|
||||
rng,
|
||||
can_gc,
|
||||
)
|
||||
.map(CryptoKeyOrCryptoKeyPair::CryptoKey),
|
||||
ALG_AES_CBC => aes_operation::generate_key_aes_cbc(
|
||||
global,
|
||||
algo,
|
||||
extractable,
|
||||
usages,
|
||||
rng,
|
||||
can_gc,
|
||||
)
|
||||
.map(CryptoKeyOrCryptoKeyPair::CryptoKey),
|
||||
ALG_AES_GCM => aes_operation::generate_key_aes_gcm(
|
||||
global,
|
||||
algo,
|
||||
extractable,
|
||||
usages,
|
||||
rng,
|
||||
can_gc,
|
||||
)
|
||||
.map(CryptoKeyOrCryptoKeyPair::CryptoKey),
|
||||
ALG_AES_KW => aes_operation::generate_key_aes_kw(
|
||||
global,
|
||||
algo,
|
||||
extractable,
|
||||
usages,
|
||||
rng,
|
||||
can_gc,
|
||||
)
|
||||
.map(CryptoKeyOrCryptoKeyPair::CryptoKey),
|
||||
ALG_AES_CTR => {
|
||||
aes_operation::generate_key_aes_ctr(global, algo, extractable, usages, can_gc)
|
||||
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
|
||||
},
|
||||
ALG_AES_CBC => {
|
||||
aes_operation::generate_key_aes_cbc(global, algo, extractable, usages, can_gc)
|
||||
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
|
||||
},
|
||||
ALG_AES_GCM => {
|
||||
aes_operation::generate_key_aes_gcm(global, algo, extractable, usages, can_gc)
|
||||
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
|
||||
},
|
||||
ALG_AES_KW => {
|
||||
aes_operation::generate_key_aes_kw(global, algo, extractable, usages, can_gc)
|
||||
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
|
||||
},
|
||||
_ => Err(Error::NotSupported),
|
||||
},
|
||||
NormalizedAlgorithm::HmacKeyGenParams(algo) => {
|
||||
hmac_operation::generate_key(global, algo, extractable, usages, rng, can_gc)
|
||||
hmac_operation::generate_key(global, algo, extractable, usages, can_gc)
|
||||
.map(CryptoKeyOrCryptoKeyPair::CryptoKey)
|
||||
},
|
||||
_ => Err(Error::NotSupported),
|
||||
|
||||
@@ -10,9 +10,9 @@ use aes_gcm::{AeadInPlace, AesGcm, KeyInit};
|
||||
use aes_kw::{KekAes128, KekAes192, KekAes256};
|
||||
use base64::prelude::*;
|
||||
use cipher::consts::{U12, U16, U32};
|
||||
use servo_rand::{RngCore, ServoRng};
|
||||
use rand::TryRngCore;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{
|
||||
CryptoKeyMethods, KeyType, KeyUsage,
|
||||
};
|
||||
@@ -108,7 +108,6 @@ pub(crate) fn generate_key_aes_ctr(
|
||||
normalized_algorithm: &SubtleAesKeyGenParams,
|
||||
extractable: bool,
|
||||
usages: Vec<KeyUsage>,
|
||||
rng: &DomRefCell<ServoRng>,
|
||||
can_gc: CanGc,
|
||||
) -> Result<DomRoot<CryptoKey>, Error> {
|
||||
generate_key_aes(
|
||||
@@ -116,7 +115,6 @@ pub(crate) fn generate_key_aes_ctr(
|
||||
normalized_algorithm,
|
||||
extractable,
|
||||
usages,
|
||||
rng,
|
||||
ALG_AES_CTR,
|
||||
&[
|
||||
KeyUsage::Encrypt,
|
||||
@@ -258,7 +256,6 @@ pub(crate) fn generate_key_aes_cbc(
|
||||
normalized_algorithm: &SubtleAesKeyGenParams,
|
||||
extractable: bool,
|
||||
usages: Vec<KeyUsage>,
|
||||
rng: &DomRefCell<ServoRng>,
|
||||
can_gc: CanGc,
|
||||
) -> Result<DomRoot<CryptoKey>, Error> {
|
||||
generate_key_aes(
|
||||
@@ -266,7 +263,6 @@ pub(crate) fn generate_key_aes_cbc(
|
||||
normalized_algorithm,
|
||||
extractable,
|
||||
usages,
|
||||
rng,
|
||||
ALG_AES_CBC,
|
||||
&[
|
||||
KeyUsage::Encrypt,
|
||||
@@ -547,7 +543,6 @@ pub(crate) fn generate_key_aes_gcm(
|
||||
normalized_algorithm: &SubtleAesKeyGenParams,
|
||||
extractable: bool,
|
||||
usages: Vec<KeyUsage>,
|
||||
rng: &DomRefCell<ServoRng>,
|
||||
can_gc: CanGc,
|
||||
) -> Result<DomRoot<CryptoKey>, Error> {
|
||||
generate_key_aes(
|
||||
@@ -555,7 +550,6 @@ pub(crate) fn generate_key_aes_gcm(
|
||||
normalized_algorithm,
|
||||
extractable,
|
||||
usages,
|
||||
rng,
|
||||
ALG_AES_GCM,
|
||||
&[
|
||||
KeyUsage::Encrypt,
|
||||
@@ -687,7 +681,6 @@ pub(crate) fn generate_key_aes_kw(
|
||||
normalized_algorithm: &SubtleAesKeyGenParams,
|
||||
extractable: bool,
|
||||
usages: Vec<KeyUsage>,
|
||||
rng: &DomRefCell<ServoRng>,
|
||||
can_gc: CanGc,
|
||||
) -> Result<DomRoot<CryptoKey>, Error> {
|
||||
generate_key_aes(
|
||||
@@ -695,7 +688,6 @@ pub(crate) fn generate_key_aes_kw(
|
||||
normalized_algorithm,
|
||||
extractable,
|
||||
usages,
|
||||
rng,
|
||||
ALG_AES_KW,
|
||||
&[KeyUsage::WrapKey, KeyUsage::UnwrapKey],
|
||||
can_gc,
|
||||
@@ -745,7 +737,6 @@ fn generate_key_aes(
|
||||
normalized_algorithm: &SubtleAesKeyGenParams,
|
||||
extractable: bool,
|
||||
usages: Vec<KeyUsage>,
|
||||
rng: &DomRefCell<ServoRng>,
|
||||
alg_name: &str,
|
||||
allowed_usages: &[KeyUsage],
|
||||
can_gc: CanGc,
|
||||
@@ -764,7 +755,10 @@ fn generate_key_aes(
|
||||
// Step 3. Generate an AES key of length equal to the length member of normalizedAlgorithm.
|
||||
// Step 4. If the key generation step fails, then throw an OperationError.
|
||||
let mut rand = vec![0; normalized_algorithm.length as usize / 8];
|
||||
rng.borrow_mut().fill_bytes(&mut rand);
|
||||
if OsRng.try_fill_bytes(&mut rand).is_err() {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
|
||||
let handle = match normalized_algorithm.length {
|
||||
128 => Handle::Aes128(rand),
|
||||
192 => Handle::Aes192(rand),
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
use aws_lc_rs::hmac;
|
||||
use base64::prelude::*;
|
||||
use rand::TryRngCore;
|
||||
use rand::rngs::OsRng;
|
||||
use script_bindings::codegen::GenericBindings::CryptoKeyBinding::CryptoKeyMethods;
|
||||
use script_bindings::domstring::DOMString;
|
||||
use servo_rand::{RngCore, ServoRng};
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::CryptoKeyBinding::{KeyType, KeyUsage};
|
||||
use crate::dom::bindings::codegen::Bindings::SubtleCryptoBinding::{JsonWebKey, KeyFormat};
|
||||
use crate::dom::bindings::error::Error;
|
||||
@@ -75,7 +75,6 @@ pub(crate) fn generate_key(
|
||||
normalized_algorithm: &SubtleHmacKeyGenParams,
|
||||
extractable: bool,
|
||||
usages: Vec<KeyUsage>,
|
||||
rng: &DomRefCell<ServoRng>,
|
||||
can_gc: CanGc,
|
||||
) -> Result<DomRoot<CryptoKey>, Error> {
|
||||
// Step 1. If usages contains any entry which is not "sign" or "verify", then throw a SyntaxError.
|
||||
@@ -107,11 +106,11 @@ pub(crate) fn generate_key(
|
||||
};
|
||||
|
||||
// Step 3. Generate a key of length length bits.
|
||||
let mut key_data = vec![0; length as usize];
|
||||
rng.borrow_mut().fill_bytes(&mut key_data);
|
||||
|
||||
// Step 4. If the key generation step fails, then throw an OperationError.
|
||||
// NOTE: Our key generation is infallible.
|
||||
let mut key_data = vec![0; length as usize];
|
||||
if OsRng.try_fill_bytes(&mut key_data).is_err() {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
|
||||
// Step 6. Let algorithm be a new HmacKeyAlgorithm.
|
||||
// Step 7. Set the name attribute of algorithm to "HMAC".
|
||||
|
||||
@@ -23,7 +23,7 @@ use net_traits::request::{
|
||||
CredentialsMode, Destination, InsecureRequestsPolicy, ParserMetadata, Referrer, RequestBuilder,
|
||||
RequestMode,
|
||||
};
|
||||
use servo_rand::random;
|
||||
use rand::random;
|
||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
use style::thread_state::{self, ThreadState};
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ use net_traits::CustomResponseMediator;
|
||||
use net_traits::request::{
|
||||
CredentialsMode, Destination, InsecureRequestsPolicy, ParserMetadata, Referrer, RequestBuilder,
|
||||
};
|
||||
use rand::random;
|
||||
use servo_config::pref;
|
||||
use servo_rand::random;
|
||||
use servo_url::ServoUrl;
|
||||
use style::thread_state::{self, ThreadState};
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ malloc_size_of_is_0!(WorkletId);
|
||||
|
||||
impl WorkletId {
|
||||
fn new() -> WorkletId {
|
||||
WorkletId(servo_rand::random_uuid())
|
||||
WorkletId(Uuid::new_v4())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,11 +34,11 @@ num-traits = { workspace = true }
|
||||
percent-encoding = { workspace = true }
|
||||
pixels = { path = "../../pixels" }
|
||||
profile_traits = { path = "../profile" }
|
||||
rand = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
rustls-pki-types = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
servo_arc = { workspace = true }
|
||||
servo_rand = { path = "../../rand" }
|
||||
servo_url = { path = "../../url" }
|
||||
url = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
|
||||
@@ -23,11 +23,11 @@ use ipc_channel::router::ROUTER;
|
||||
use malloc_size_of::malloc_size_of_is_0;
|
||||
use malloc_size_of_derive::MallocSizeOf;
|
||||
use mime::Mime;
|
||||
use rand::{RngCore, rng};
|
||||
use request::RequestId;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustls_pki_types::CertificateDer;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use servo_rand::RngCore;
|
||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
|
||||
use crate::filemanager_thread::FileManagerThreadMsg;
|
||||
@@ -1107,5 +1107,4 @@ pub fn set_default_accept_language(headers: &mut HeaderMap) {
|
||||
);
|
||||
}
|
||||
|
||||
pub static PRIVILEGED_SECRET: LazyLock<u32> =
|
||||
LazyLock::new(|| servo_rand::ServoRng::default().next_u32());
|
||||
pub static PRIVILEGED_SECRET: LazyLock<u32> = LazyLock::new(|| rng().next_u32());
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct RequestId(pub Uuid);
|
||||
|
||||
impl Default for RequestId {
|
||||
fn default() -> Self {
|
||||
Self(servo_rand::random_uuid())
|
||||
Self(Uuid::new_v4())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ doctest = false
|
||||
encoding_rs = { workspace = true }
|
||||
malloc_size_of = { workspace = true }
|
||||
malloc_size_of_derive = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
servo_arc = { workspace = true }
|
||||
servo_rand = { path = "../rand" }
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
uuid = { workspace = true, features = ["serde"] }
|
||||
|
||||
@@ -40,14 +40,12 @@ impl ImmutableOrigin {
|
||||
|
||||
/// Creates a new opaque origin that is only equal to itself.
|
||||
pub fn new_opaque() -> ImmutableOrigin {
|
||||
ImmutableOrigin::Opaque(OpaqueOrigin::Opaque(servo_rand::random_uuid()))
|
||||
ImmutableOrigin::Opaque(OpaqueOrigin::Opaque(Uuid::new_v4()))
|
||||
}
|
||||
|
||||
// For use in mixed security context tests because data: URL workers inherit contexts
|
||||
pub fn new_opaque_data_url_worker() -> ImmutableOrigin {
|
||||
ImmutableOrigin::Opaque(OpaqueOrigin::SecureWorkerFromDataUrl(
|
||||
servo_rand::random_uuid(),
|
||||
))
|
||||
ImmutableOrigin::Opaque(OpaqueOrigin::SecureWorkerFromDataUrl(Uuid::new_v4()))
|
||||
}
|
||||
|
||||
pub fn scheme(&self) -> Option<&str> {
|
||||
|
||||
11
deny.toml
11
deny.toml
@@ -70,17 +70,6 @@ allow = []
|
||||
# List of crates to deny:
|
||||
deny = [
|
||||
"num",
|
||||
# cargo-deny does not allow denying the rand crate while also skipping
|
||||
# it for duplicate checks. While the ecosystem is split between 0.8 and 0.9,
|
||||
# we need to prioritize allowing duplicate versions.
|
||||
#{ crate = "rand", wrappers = [
|
||||
# "ipc-channel",
|
||||
# "phf_generator",
|
||||
# "quickcheck",
|
||||
# "servo_rand",
|
||||
# "tracing-perfetto",
|
||||
# "tungstenite",
|
||||
#] },
|
||||
]
|
||||
|
||||
# List of crates to skip for the duplicate check:
|
||||
|
||||
Reference in New Issue
Block a user