align / code /bugfind /bench /make_kernels.py
viai957's picture
Add files using upload-large-folder tool
4951e76 verified
Raw History Blame Contribute Delete
25.2 kB
#!/usr/bin/env python3 -I
"""Minimal-extraction items (Phase 5 Part A, "extract the affected pure function into a minimal standalone crate").
Each KERNEL is a hand-extracted, dependency-free reduction of the *decision logic* that a RustSec fix changed
(pre = vulnerable revision's logic, post = patched revision's logic). Whole crates are not translatable (native deps,
dyn traits, early returns in loops, ...: see TOOLCHAIN.md / SUMMARY.json), so the unit is the function kernel.
`fidelity`:
verbatim_logic the changed expression/branch is copied from the crate with std/crate types replaced by integers/slices
model_of_std the vulnerable behaviour lives in a std/crate call (slice split_at, str slicing, unchecked memcpy length);
the kernel models that call's panic/UB condition explicitly. Weaker; reported separately.
Extraction was done by reading the pre/post diff, so kernels are NOT blind to the bug; only the *properties* (property bank)
are authored blind, from `spec_doc` + signature alone (see baselines/bank/README_PROVENANCE.md).
Writes bench/kernels/<id>/{meta.json,pre/{Cargo.toml,src/lib.rs},post/{Cargo.toml,src/lib.rs}}.
"""
import json, os
HERE = os.path.dirname(os.path.abspath(__file__))
CAND = "/apps/development/rlhf/bugfind_data/out/advisory_candidates.jsonl"
K = []
def k(kid, adv, fn, sig, spec_doc, bug_class, fidelity, pre, post, witness, note, file):
K.append(dict(id=kid, adv=adv, fn=fn, sig=sig, spec_doc=spec_doc, bug_class=bug_class, fidelity=fidelity,
pre=pre.strip() + "\n", post=post.strip() + "\n", witness=witness, note=note, file=file))
k("claxon_rice", "RUSTSEC-2018-0004", "rice_layout", "pub fn rice_layout(block_size: u16, order: u32, n_warm_up: u16) -> Result<u32, u8>",
"Computes how many residual samples a FLAC Rice-coded subframe's 2^order partitions cover (order is a 4-bit field, so order > 15 is rejected with Err). On Ok(n), n must equal block_size (the partitions fill the block); otherwise return Err.",
"logic", "verbatim_logic",
"""
pub fn rice_layout(block_size: u16, order: u32, n_warm_up: u16) -> Result<u32, u8> {
if order > 15 {
return Err(3);
}
let n_partitions = 1u32 << order;
let n_samples_per_partition = block_size >> order;
if n_warm_up > n_samples_per_partition {
return Err(1);
}
Ok(n_partitions * (n_samples_per_partition as u32))
}
""", """
pub fn rice_layout(block_size: u16, order: u32, n_warm_up: u16) -> Result<u32, u8> {
if order > 15 {
return Err(3);
}
let n_partitions = 1u32 << order;
let n_samples_per_partition = block_size >> order;
if block_size & ((n_partitions - 1) as u16) != 0 {
return Err(2);
}
if n_warm_up > n_samples_per_partition {
return Err(1);
}
Ok(n_partitions * (n_samples_per_partition as u32))
}
""", "10u16, 2u32, 0u16", "src/subframe.rs decode_residual: block size not a multiple of 2^order left buffer tail uninitialised", "src/subframe.rs")
k("bytes_reserve", "RUSTSEC-2026-0007", "reserve_fits", "pub fn reserve_fits(v_capacity: usize, new_cap: usize, offset: usize) -> bool",
"Decides whether a Vec-backed buffer with capacity v_capacity can serve a reserve request of new_cap bytes when the live window starts at offset; must be true iff v_capacity >= new_cap + offset in exact arithmetic.",
"overflow", "verbatim_logic",
"pub fn reserve_fits(v_capacity: usize, new_cap: usize, offset: usize) -> bool {\n v_capacity >= new_cap + offset\n}",
"""
pub fn reserve_fits(v_capacity: usize, new_cap: usize, offset: usize) -> bool {
match new_cap.checked_add(offset) {
Some(s) => v_capacity >= s,
None => false,
}
}
""", "10usize, usize::MAX, 1usize", "src/bytes_mut.rs reserve_inner: new_cap + offset overflow", "src/bytes_mut.rs")
k("mldsa_hint", "RUSTSEC-2026-0076", "hint_weight", "pub fn hint_weight(hint: &[u8], max_ones: usize, rows: usize) -> Option<usize>",
"Decodes the ML-DSA signature hint encoding: hint[..max_ones] are positions, hint[max_ones..max_ones+rows] are cumulative counts that must be non-decreasing and at most max_ones. Returns the sum of the hint bytes it consumed, or None for a malformed encoding. Must never panic on any input of length >= max_ones+rows.",
"panic", "verbatim_logic",
"""
pub fn hint_weight(hint: &[u8], max_ones: usize, rows: usize) -> Option<usize> {
let mut previous = 0usize;
let mut total = 0usize;
let mut bad = false;
let mut i = 0usize;
while i < rows {
let current = hint[max_ones + i] as usize;
if current < previous || previous > max_ones {
bad = true;
} else {
let mut j = previous;
while j < current {
total += hint[j] as usize;
j += 1;
}
previous = current;
}
i += 1;
}
if bad { None } else { Some(total) }
}
""", """
pub fn hint_weight(hint: &[u8], max_ones: usize, rows: usize) -> Option<usize> {
let mut previous = 0usize;
let mut total = 0usize;
let mut bad = false;
let mut i = 0usize;
while i < rows {
let current = hint[max_ones + i] as usize;
if current < previous || current > max_ones {
bad = true;
} else {
let mut j = previous;
while j < current {
total += hint[j] as usize;
j += 1;
}
previous = current;
}
i += 1;
}
if bad { None } else { Some(total) }
}
""", "&[0u8, 0, 200], 2usize, 1usize", "src/ml_dsa_generic.rs / encoding/signature.rs deserialize hint: checked previous instead of current against max_ones", "src/encoding/signature.rs")
k("mldsa_norm", "RUSTSEC-2026-0076", "response_bound", "pub fn response_bound(gamma1_exponent: u32, beta: i32) -> i32",
"ML-DSA verification bound for the signer response: gamma1 - beta where gamma1 = 2^gamma1_exponent.",
"logic", "verbatim_logic",
"pub fn response_bound(gamma1_exponent: u32, beta: i32) -> i32 {\n (2i32 << gamma1_exponent) - beta\n}",
"pub fn response_bound(gamma1_exponent: u32, beta: i32) -> i32 {\n (1i32 << gamma1_exponent) - beta\n}",
"17u32, 78i32", "src/ml_dsa_generic.rs verify: (2 << GAMMA1_EXPONENT) - BETA instead of (1 << ...) - BETA", "src/ml_dsa_generic.rs")
k("odoh_split", "RUSTSEC-2023-0095", "encrypted_payload_len", "pub fn encrypted_payload_len(msg: &[u8], key_size: usize) -> Result<usize, u8>",
"Splits an encrypted ODoH query into an encapsulated key (first key_size bytes) and ciphertext (the rest); returns the ciphertext length, or Err if the message is shorter than key_size. Must not panic on any input.",
"panic", "model_of_std",
"pub fn encrypted_payload_len(msg: &[u8], key_size: usize) -> Result<usize, u8> {\n let ct = &msg[key_size..];\n Ok(ct.len())\n}",
"pub fn encrypted_payload_len(msg: &[u8], key_size: usize) -> Result<usize, u8> {\n if key_size > msg.len() {\n return Err(1);\n }\n let ct = &msg[key_size..];\n Ok(ct.len())\n}",
"&[1u8, 2, 3], 32usize", "src/protocol.rs decrypt_query: split_at(key_size) without length check", "src/protocol.rs")
k("matrix_power", "RUSTSEC-2025-0065", "normalize_power_level", "pub fn normalize_power_level(power_level: i64, max_power_level: i64) -> i64",
"Scales a Matrix user power level (|power_level| < 2^53) to the range 0..=100 relative to max_power_level > 0.",
"panic", "verbatim_logic",
"""
const INT_MAX: i64 = 9007199254740991;
pub fn normalize_power_level(power_level: i64, max_power_level: i64) -> i64 {
let n = (power_level * 100) / max_power_level;
assert!(n >= -INT_MAX && n <= INT_MAX);
n
}
""", """
pub fn normalize_power_level(power_level: i64, max_power_level: i64) -> i64 {
let n = (power_level * 100) / max_power_level;
if n < 0 {
0
} else if n > 100 {
100
} else {
n
}
}
""", "9007199254740991i64, 1i64", "src/room/members.rs normalized_power_level: expect() on out-of-range Int when max_power_level is small", "src/room/members.rs")
k("nostr_iv", "RUSTSEC-2026-0219", "load_iv", "pub fn load_iv(iv: &[u8]) -> Result<[u8; 16], u8>",
"Loads a NIP-04 AES-CBC initialisation vector from untrusted bytes; must return Err unless the input is exactly 16 bytes, and must never panic.",
"panic", "model_of_std",
"""
pub fn load_iv(iv: &[u8]) -> Result<[u8; 16], u8> {
let mut out = [0u8; 16];
let mut i = 0usize;
while i < 16 {
out[i] = iv[i];
i += 1;
}
Ok(out)
}
""", """
pub fn load_iv(iv: &[u8]) -> Result<[u8; 16], u8> {
if iv.len() != 16 {
return Err(1);
}
let mut out = [0u8; 16];
let mut i = 0usize;
while i < 16 {
out[i] = iv[i];
i += 1;
}
Ok(out)
}
""", "&[1u8, 2, 3]", "src/nips/nip04.rs decrypt: iv.as_slice().into() panics on wrong length", "src/nips/nip04.rs")
k("phone_ctx", "RUSTSEC-2023-0082", "context_prefix_skip", "pub fn context_prefix_skip(s: &[u8]) -> usize",
"Returns how many leading bytes of an RFC3966 phone-context value to skip: 1 if it starts with '+', otherwise 0. Must not panic on empty input.",
"panic", "verbatim_logic",
"pub fn context_prefix_skip(s: &[u8]) -> usize {\n if s[0] == b'+' { 1 } else { 0 }\n}",
"pub fn context_prefix_skip(s: &[u8]) -> usize {\n if !s.is_empty() && s[0] == b'+' { 1 } else { 0 }\n}",
"&[]", "src/parser/rfc3966.rs: s.as_bytes()[0] on empty phone-context", "src/parser/rfc3966.rs")
k("poly1305_key", "RUSTSEC-2026-0073", "key_len_ok", "pub fn key_len_ok(key: &[u8]) -> bool",
"Poly1305 one-time keys are r (16 bytes) followed by s (16 bytes): a key is acceptable iff it is exactly 32 bytes.",
"logic", "verbatim_logic",
"pub const KEY_LEN: usize = 16;\npub fn key_len_ok(key: &[u8]) -> bool {\n key.len() == KEY_LEN\n}",
"pub const KEY_LEN: usize = 32;\npub fn key_len_ok(key: &[u8]) -> bool {\n key.len() == KEY_LEN\n}",
"&[0u8; 32]", "src/lib.rs KEY_LEN = 16 (standalone mac rejected/panicked on real 32-byte keys)", "src/lib.rs")
k("ecdh_scalar", "RUSTSEC-2026-0023", "validate_x25519_scalar", "pub fn validate_x25519_scalar(s: &[u8]) -> bool",
"Validates an X25519 secret scalar: must be exactly 32 bytes, not all zero, and clamped (low 3 bits of byte 0 clear, top bit of byte 31 clear, second-highest bit of byte 31 set).",
"logic", "verbatim_logic",
"""
pub fn validate_x25519_scalar(s: &[u8]) -> bool {
let mut all_zero = true;
let mut i = 0usize;
while i < s.len() {
if s[i] != 0 {
all_zero = false;
}
i += 1;
}
!all_zero
}
""", """
pub fn validate_x25519_scalar(s: &[u8]) -> bool {
if s.len() != 32 {
return false;
}
let mut all_zero = true;
let mut i = 0usize;
while i < s.len() {
if s[i] != 0 {
all_zero = false;
}
i += 1;
}
if all_zero {
return false;
}
(s[0] & 7) == 0 && (s[31] & 128) == 0 && (s[31] & 64) != 0
}
""", "&[1u8, 2, 3]", "src/ecdh.rs validate_scalar: only checked all-zero", "src/ecdh.rs")
k("nanoid_mask", "RUSTSEC-2024-0343", "alphabet_mask", "pub fn alphabet_mask(len: usize) -> usize",
"Bit mask used to index an alphabet of len symbols (len >= 2) from a random byte: the smallest all-ones value m with m >= len - 1, i.e. next_power_of_two(len) - 1.",
"logic", "verbatim_logic",
"pub fn alphabet_mask(len: usize) -> usize {\n len - 1\n}",
"""
pub fn alphabet_mask(len: usize) -> usize {
let mut p = 1usize;
while p < len {
p = p * 2;
}
p - 1
}
""", "62usize", "src/lib.rs MASK = $len - 1 is not a bit mask for non-power-of-two alphabets (biased/short alphabet)", "src/lib.rs")
k("tar_pax", "RUSTSEC-2026-0145", "apply_pax", "pub fn apply_pax(entry_type: u8, has_pax: bool) -> bool",
"PAX extended-header data describes the next file entry. Returns whether pending PAX data must be applied to a header of the given type byte: only for real entries, never for GNU long-name 'L', long-link 'K', PAX local 'x' or global 'g' headers.",
"logic", "verbatim_logic",
"pub fn apply_pax(entry_type: u8, has_pax: bool) -> bool {\n has_pax\n}",
"""
pub fn apply_pax(entry_type: u8, has_pax: bool) -> bool {
let mut is_extension_header = false;
if entry_type == b'L' || entry_type == b'K' || entry_type == b'x' || entry_type == b'g' {
is_extension_header = true;
}
if has_pax {
if is_extension_header { false } else { true }
} else {
false
}
}
""", "b'L', true", "src/archive.rs: PAX data applied to extension headers (desynchronisation)", "src/archive.rs")
k("exif_discard", "RUSTSEC-2021-0143", "discard_exact", "pub fn discard_exact(avail: usize, len: usize) -> Result<usize, u8>",
"Models skipping len bytes of a reader that has only avail bytes: returns Ok(number of read rounds) when the reader had enough data, Err when it hits EOF early. Must terminate on every input.",
"dos_loop_or_recursion", "verbatim_logic",
"""
pub fn discard_exact(avail: usize, len: usize) -> Result<usize, u8> {
let mut avail = avail;
let mut len = len;
let mut rounds = 0usize;
while len > 0 {
let consume_len = if avail < len { avail } else { len };
avail -= consume_len;
len -= consume_len;
rounds += 1;
}
Ok(rounds)
}
""", """
pub fn discard_exact(avail: usize, len: usize) -> Result<usize, u8> {
let mut avail = avail;
let mut len = len;
let mut rounds = 0usize;
let mut eof = false;
while len > 0 && !eof {
let consume_len = if avail < len { avail } else { len };
if consume_len == 0 {
eof = true;
} else {
avail -= consume_len;
len -= consume_len;
rounds += 1;
}
}
if eof { Err(1) } else { Ok(rounds) }
}
""", "3usize, 10usize", "src/util.rs discard_exact: spins forever at EOF (consume_len == 0)", "src/util.rs")
k("trustdns_ptr", "RUSTSEC-2018-0007", "pointer_ok", "pub fn pointer_ok(location: usize, pointer_location: usize, name_start: usize) -> bool",
"A DNS name-compression pointer is acceptable iff its target lies strictly before the start of the name currently being parsed (so pointer chains cannot loop).",
"dos_loop_or_recursion", "verbatim_logic",
"pub fn pointer_ok(location: usize, pointer_location: usize, name_start: usize) -> bool {\n let _ = name_start;\n location < pointer_location\n}",
"pub fn pointer_ok(location: usize, pointer_location: usize, name_start: usize) -> bool {\n let _ = pointer_location;\n location < name_start\n}",
"0usize, 2usize, 0usize", "src/rr/domain/name.rs Name::read: pointer compared with current label instead of name start (self-referential name)", "src/rr/domain/name.rs")
k("ring_ctr", "RUSTSEC-2025-0009", "increment_by", "pub fn increment_by(old_value: u32, increment_by: u32) -> u32",
"Increments a 32-bit big-endian AES-GCM block counter, wrapping modulo 2^32.",
"overflow", "verbatim_logic",
"pub fn increment_by(old_value: u32, increment_by: u32) -> u32 {\n old_value + increment_by\n}",
"pub fn increment_by(old_value: u32, increment_by: u32) -> u32 {\n old_value.wrapping_add(increment_by)\n}",
"4294967295u32, 1u32", "src/aead/aes.rs increment_by_less_safe: + panics with overflow checks", "src/aead/aes.rs")
k("stack_insert", "RUSTSEC-2020-0042", "insert_shift_len", "pub fn insert_shift_len(len: usize, index: usize) -> Result<usize, u8>",
"Number of elements to shift when inserting at index into a vector of length len; Err if index > len.",
"panic", "model_of_std",
"pub fn insert_shift_len(len: usize, index: usize) -> Result<usize, u8> {\n Ok(len.wrapping_sub(index))\n}",
"pub fn insert_shift_len(len: usize, index: usize) -> Result<usize, u8> {\n if index > len {\n return Err(1);\n }\n Ok(len - index)\n}",
"3usize, 5usize", "src/vector.rs insert: missing index <= len assert; copy length len - index wrapped (release) -> OOB write", "src/vector.rs")
k("tract_len", "RUSTSEC-2026-0217", "tensor_len_ok", "pub fn tensor_len_ok(dims: &[usize], bits_per_item: usize, data_size_bytes: usize) -> bool",
"NNEF tensor header consistency: true iff prod(dims) * (bits_per_item / 8) == data_size_bytes in exact arithmetic (false if the product does not fit usize).",
"overflow", "verbatim_logic",
"""
pub fn tensor_len_ok(dims: &[usize], bits_per_item: usize, data_size_bytes: usize) -> bool {
let mut len = 1usize;
let mut i = 0usize;
while i < dims.len() {
len = len * dims[i];
i += 1;
}
len * (bits_per_item / 8) == data_size_bytes
}
""", """
pub fn tensor_len_ok(dims: &[usize], bits_per_item: usize, data_size_bytes: usize) -> bool {
let mut len = 1usize;
let mut overflow = false;
let mut i = 0usize;
while i < dims.len() {
let d = dims[i];
if d != 0 && len > usize::MAX / d {
overflow = true;
} else {
len = len * d;
}
i += 1;
}
if overflow {
return false;
}
let per = bits_per_item / 8;
if per != 0 && len > usize::MAX / per {
return false;
}
len * per == data_size_bytes
}
""", "&[4294967296usize, 4294967296], 8usize, 0usize", "src/tensors.rs read_tensor: unchecked shape product", "src/tensors.rs")
k("transpose_dims", "RUSTSEC-2023-0080", "dims_match", "pub fn dims_match(width: usize, height: usize, len: usize) -> bool",
"True iff width * height == len in exact arithmetic (false when the product does not fit usize).",
"overflow", "verbatim_logic",
"pub fn dims_match(width: usize, height: usize, len: usize) -> bool {\n width * height == len\n}",
"pub fn dims_match(width: usize, height: usize, len: usize) -> bool {\n match width.checked_mul(height) {\n Some(p) => p == len,\n None => false,\n }\n}",
"4294967296usize, 4294967296usize, 0usize", "src/lib.rs transpose: assert_eq!(w*h, len) wraps in release -> buffer overflow", "src/lib.rs")
k("toodee_drain", "RUSTSEC-2025-0062", "drain_col_copy_len", "pub fn drain_col_copy_len(orig_cols: usize, col: usize) -> usize",
"When removing column col from a row of orig_cols cells, the number of cells to shift left: those strictly after col (orig_cols - col - 1).",
"overflow", "verbatim_logic",
"pub fn drain_col_copy_len(orig_cols: usize, col: usize) -> usize {\n orig_cols - col\n}",
"pub fn drain_col_copy_len(orig_cols: usize, col: usize) -> usize {\n orig_cols - col - 1\n}",
"5usize, 2usize", "src/toodee.rs DrainCol::drop: ptr::copy length off by one (heap overflow)", "src/toodee.rs")
k("tinyhttp_hdr", "RUSTSEC-2020-0031", "header_field_ok", "pub fn header_field_ok(s: &[u8]) -> bool",
"A header field name is valid iff it is ASCII and contains no whitespace (no trimming: ' Transfer-Encoding' and 'Transfer-Encoding ' are invalid).",
"logic", "verbatim_logic",
"""
fn is_ws(b: u8) -> bool {
b == b' ' || b == b'\\t' || b == b'\\n' || b == b'\\r' || b == 11u8 || b == 12u8
}
pub fn header_field_ok(s: &[u8]) -> bool {
let mut start = 0usize;
let mut end = s.len();
while start < end && is_ws(s[start]) {
start += 1;
}
while end > start && is_ws(s[end - 1]) {
end -= 1;
}
let mut ok = true;
let mut i = start;
while i < end {
if s[i] >= 128 {
ok = false;
}
i += 1;
}
ok
}
""", """
fn is_ws(b: u8) -> bool {
b == b' ' || b == b'\\t' || b == b'\\n' || b == b'\\r' || b == 11u8 || b == 12u8
}
pub fn header_field_ok(s: &[u8]) -> bool {
let mut ok = true;
let mut i = 0usize;
while i < s.len() {
if s[i] >= 128 || is_ws(s[i]) {
ok = false;
}
i += 1;
}
ok
}
""", "b\"Transfer-Encoding \"", "src/common.rs HeaderField::from_str: trimmed whitespace (request smuggling)", "src/common.rs")
k("evm_memset", "RUSTSEC-2021-0066", "memory_set_len", "pub fn memory_set_len(cur_len: usize, offset: usize, value_len: usize, target_size: Option<usize>, limit: usize) -> Result<usize, u8>",
"New length of EVM memory after writing value (value_len bytes) at offset, zero-padded to target_size (default value_len). Err if offset+target_size exceeds limit. Writing an empty value must not grow memory.",
"dos_loop_or_recursion", "verbatim_logic",
"""
pub fn memory_set_len(cur_len: usize, offset: usize, value_len: usize, target_size: Option<usize>, limit: usize) -> Result<usize, u8> {
let target = match target_size {
Some(t) => t,
None => value_len,
};
match offset.checked_add(target) {
Some(pos) => {
if pos > limit {
return Err(1);
}
}
None => return Err(1),
}
if cur_len < offset + target {
Ok(offset + target)
} else {
Ok(cur_len)
}
}
""", """
pub fn memory_set_len(cur_len: usize, offset: usize, value_len: usize, target_size: Option<usize>, limit: usize) -> Result<usize, u8> {
if value_len == 0 {
return Ok(cur_len);
}
let target = match target_size {
Some(t) => t,
None => value_len,
};
match offset.checked_add(target) {
Some(pos) => {
if pos > limit {
return Err(1);
}
}
None => return Err(1),
}
if cur_len < offset + target {
Ok(offset + target)
} else {
Ok(cur_len)
}
}
""", "0usize, 0usize, 0usize, Some(1000usize), 1048576usize", "src/memory.rs Memory::set: empty value with large target_size over-allocates", "src/memory.rs")
k("bcrypt_split", "RUSTSEC-2026-0199", "split_hash_salt_len", "pub fn split_hash_salt_len(hash: &[u8]) -> Result<usize, u8>",
"Validates a bcrypt hash string and returns the salt length (22). A valid hash is exactly 60 ASCII bytes; every other input must give Err, never panic.",
"panic", "model_of_std",
"""
fn is_char_boundary(b: u8) -> bool {
b < 128 || b >= 192
}
pub fn split_hash_salt_len(hash: &[u8]) -> Result<usize, u8> {
if hash.len() != 60 {
return Err(1);
}
assert!(is_char_boundary(hash[22]));
Ok(22)
}
""", """
pub fn split_hash_salt_len(hash: &[u8]) -> Result<usize, u8> {
if hash.len() != 60 {
return Err(1);
}
let mut ascii = true;
let mut i = 0usize;
while i < hash.len() {
if hash[i] >= 128 {
ascii = false;
}
i += 1;
}
if !ascii {
return Err(2);
}
Ok(22)
}
""", "&[b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', 0xA3, b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a', b'a']",
"src/lib.rs split_hash: &str slicing at a non-char-boundary on non-ASCII 60-byte input", "src/lib.rs")
k("versionize_fam", "RUSTSEC-2023-0030", "fam_entry", "pub fn fam_entry(entries: &[u32], header_len: usize, i: usize) -> Result<u32, u8>",
"Reads entry i (< header_len) of a deserialised flexible-array struct whose header declares header_len entries; Err if the header length disagrees with the actual number of entries, never panic.",
"panic", "model_of_std",
"pub fn fam_entry(entries: &[u32], header_len: usize, i: usize) -> Result<u32, u8> {\n if i < header_len {\n Ok(entries[i])\n } else {\n Err(2)\n }\n}",
"pub fn fam_entry(entries: &[u32], header_len: usize, i: usize) -> Result<u32, u8> {\n if header_len != entries.len() {\n return Err(1);\n }\n if i < header_len {\n Ok(entries[i])\n } else {\n Err(2)\n }\n}",
"&[7u32, 8], 5usize, 3usize", "src/primitives.rs FamStructWrapper::deserialize: header length not checked against entries", "src/primitives.rs")
def main():
cand = {}
for l in open(CAND):
r = json.loads(l); cand[r["adv_id"]] = r
root = os.path.join(HERE, "kernels")
for e in K:
c = cand[e["adv"]]
d = os.path.join(root, e["id"])
for ver in ("pre", "post"):
os.makedirs(f"{d}/{ver}/src", exist_ok=True)
open(f"{d}/{ver}/Cargo.toml", "w").write(f'[package]\nname = "k_{e["id"]}_{ver}"\nversion = "0.1.0"\nedition = "2021"\n\n[lib]\npath = "src/lib.rs"\n\n[workspace]\n')
open(f"{d}/{ver}/src/lib.rs", "w").write(e[ver])
meta = dict(item_id=f"ker-{e['id']}", kernel=e["id"], advisory=e["adv"], crate=c["crate"], pre_version=c["pre_version"], post_version=c["post_version"],
advisory_url=c["url"], title=c["title"], source_file=e["file"], function=e["fn"], signature=e["sig"], spec_doc=e["spec_doc"],
bug_class=e["bug_class"], fidelity=e["fidelity"], extraction_note=e["note"], witness_args=e["witness"],
labels={"buggy": f"{c['crate']}@{c['pre_version']}", "reference": f"{c['crate']}@{c['post_version']}"})
json.dump(meta, open(f"{d}/meta.json", "w"), indent=1)
print(len(K), "kernels written to", root)
if __name__ == "__main__":
main()