Source
ghsa
When parsing JSON using `json::Json::from_str`, there is no limit to the depth of the stack, therefore deeply nested objects can cause a stack overflow, which aborts the process. Example code that triggers the vulnerability is ```rust fn main() { let _ = rustc_serialize::json::Json::from_str(&"[0,[".repeat(10000)); } ``` [serde](https://crates.io/crates/serde) is recommended as a replacement to rustc_serialize.
When running in debug mode and the `debug-embed` (off by default) feature is not enabled, the generated `get` method does not check that the input path is a child of the folder given. This allows attackers to read arbitrary files in the file system if they have control over the filename given. The following code will print the contents of your `/etc/passwd` if adjusted with a correct number of `../`s depending on where it is run from. ```rust #[derive(rust_embed::RustEmbed)] #[folder = "src/"] pub struct Asset; fn main() { let d = Asset::get("../../../etc/passwd").unwrap().data; println!("{}", String::from_utf8_lossy(&d)); } ``` The flaw was corrected by canonicalizing the input filename and ensuring that it starts with the canonicalized folder path.
The following Rust program demonstrates some strangeness in AES encryption - if you have an immutable key slice and then operate on that slice, you get different encryption output than if you operate on a copy of that key. For these functions, we expect that extending a 16 byte key to a 32 byte key by repeating it gives the same encrypted data, because the underlying rust-crypto functions repeat key data up to the necessary key size for the cipher. ```rust use crypto::{ aes, blockmodes, buffer, buffer::{BufferResult, ReadBuffer, WriteBuffer}, symmetriccipher, }; fn encrypt( key: &[u8], iv: &[u8], data: &str, ) -> Result<String, symmetriccipher::SymmetricCipherError> { let mut encryptor = aes::cbc_encryptor(aes::KeySize::KeySize256, key, iv, blockmodes::PkcsPadding); let mut encrypted_data = Vec::<u8>::new(); let mut read_buffer = buffer::RefReadBuffer::new(data.as_bytes()); let mut buffer = [0; 4096]; let mut write_buffer = buffer...
The lifetime bound on several closure-accepting `rusqlite` functions (specifically, functions which register a callback to be later invoked by SQLite) was too relaxed. If a closure referencing borrowed values on the stack is was passed to one of these functions, it could allow Rust code to access objects on the stack after they have been dropped. The impacted functions are: - Under `cfg(feature = "functions")`: `Connection::create_scalar_function`, `Connection::create_aggregate_function` and `Connection::create_window_function`. - Under `cfg(feature = "hooks")`: `Connection::commit_hook`, `Connection::rollback_hook` and `Connection::update_hook`. - Under `cfg(feature = "collation")`: `Connection::create_collation`. The issue exists in all `0.25.*` versions prior to `0.25.4`, and all `0.26.*` versions prior to 0.26.2 (specifically: `0.25.0`, `0.25.1`, `0.25.2`, `0.25.3`, `0.26.0`, and `0.26.1`). The fix is available in versions `0.26.2` and newer, and also has been back-ported to `0...
When activating the non-default feature `serialize`, most structs implement `serde::Deserialize` without sufficient validation. This allows breaking invariants in safe code, leading to: * Undefined behavior in `as_string()` methods (which use `std::str::from_utf8_unchecked()` internally). * Panics due to failed assertions. See https://github.com/gz/rust-cpuid/issues/43.
This is impossible to do by accident, but by carefully constructing marker types to be covariant, a malicious coder can cheat the singleton check in `TCellOwner` and `TLCellOwner`, giving unsound access to cell memory. This could take the form of getting two mutable references to the same memory, or a mutable reference and an immutable reference. The fix is for the crate to internally force the marker type to be invariant. This blocks the conversion between covariant types which Rust normally allows.
`rdiff` performs a diff of two provided strings or files. As part of its reading code it uses the return value of a `Read` instance to set the length of its internal character vector. If the `Read` implementation claims that it has read more bytes than the length of the provided buffer, the length of the vector will be set to longer than its capacity. This causes `rdiff` APIs to return uninitialized memory in its API methods.
On certain platforms, if a user has more than 16 groups, the `nix::unistd::getgrouplist` function will call the libc `getgrouplist` function with a length parameter greater than the size of the buffer it provides, resulting in an out-of-bounds write and memory corruption. The libc `getgrouplist` function takes an in/out parameter `ngroups` specifying the size of the group buffer. When the buffer is too small to hold all of the reqested user's group memberships, some libc implementations, including glibc and Solaris libc, will modify `ngroups` to indicate the actual number of groups for the user, in addition to returning an error. The version of `nix::unistd::getgrouplist` in nix 0.16.0 and up will resize the buffer to twice its size, but will not read or modify the `ngroups` variable. Thus, if the user has more than twice as many groups as the initial buffer size of 8, the next call to `getgrouplist` will then write past the end of the buffer. The issue would require editing /etc/gro...
Neon provides functionality for creating JavaScript `ArrayBuffer` (and the `Buffer` subtype) instances backed by bytes allocated outside of V8/Node. The [`JsArrayBuffer::external`](https://docs.rs/neon/0.10.0/neon/types/struct.JsArrayBuffer.html#method.external) and [`JsBuffer::external`](https://docs.rs/neon/0.10.0/neon/types/struct.JsBuffer.html#method.external) did not require `T: 'static` prior to Neon `0.10.1`. This allowed creating an externally backed buffer from types that may be freed while they are still referenced by a JavaScript `ArrayBuffer`. The following example demonstrates use after free. It compiles on versions `<0.10.1` and fails to compile afterward. ```rust pub fn soundness_hole(mut cx: FunctionContext) -> JsResult<JsArrayBuffer> { let mut data = vec![0u8, 1, 2, 3]; // Creating an external from `&mut [u8]` instead of `Vec<u8>` since there is a blanket impl // of `AsMut<T> for &mut T` let buf = JsArrayBuffer::external(&mut cx, data.as_mut_slic...
`TlsWyRand`'s implementation of `Deref` unconditionally dereferences a raw pointer, and returns multiple mutable references to the same object, which is undefined behavior.