oxidecomputer / oxidecomputer/omicron
Oximeter timeseries schema may in some cases only allow 254 target versions
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 572
- Forks
- 97
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 96
Description
version is defined as a NonZero<u8>, when parsing the timeseries definitions into a schema list it is zipped with 1u8.., this causes some issues since the current range implementation will panic one before the end when built with overflow-checks. This means that when running it in debug will not be able to parse a file with version 1 to and including 255, but it will do so in release.
This also means that it will give some rather odd diagnostics when reaching the limit such as
`Err` value: SchemaDefinition("Target 'target' versions should be sequential and monotonically increasing (expected 0, found 255)")
if you have more fields than 255. of course you cannot have a version 0 because it is a non-zero type.
A sidenote is that switching it to be a RangeFrom over NonZero<u8> will not resolve the issue as the RangeFrom will in that case saturate and may allow multiple version 255.
MRE for a panic with `overflow-checks`
To be placed in `omicron/oximeter/schema/src/ir.rs` ```rust #[test] fn way_too_many_target_versions() { let contents = r#" format_version = 1 [target]
name = "target"
description = "some target"
authz_scope = "fleet"
versions = [
{ version = 1, fields = [ "foo" ] },
{ version = 2, fields = [ "foo" ] },
{ version = 3, fields = [ "foo" ] },
{ version = 4, fields = [ "foo" ] },
{ version = 5, fields = [ "foo" ] },
{ version = 6, fields = [ "foo" ] },
{ version = 7, fields = [ "foo" ] },
{ version = 8, fields = [ "foo" ] },
{ version = 9, fields = [ "foo" ] },
{ version = 10, fields = [ "foo" ] },
{ version = 11, fields = [ "foo" ] },
{ version = 12, fields = [ "foo" ] },
{ version = 13, fields = [ "foo" ] },
{ version = 14, fields = [ "foo" ] },
{ version = 15, fields = [ "foo" ] },
{ version = 16, fields = [ "foo" ] },
{ version = 17, fields = [ "foo" ] },
{ version = 18, fields = [ "foo" ] },
{ version = 19, fields = [ "foo" ] },
{ version = 20, fields = [ "foo" ] },
{ version = 21, fields = [ "foo" ] },
{ version = 22, fields = [ "foo" ] },
{ version = 23, fields = [ "foo" ] },
{ version = 24, fields = [ "foo" ] },
{ version = 25, fields = [ "foo" ] },
{ version = 26, fields = [ "foo" ] },
{ version = 27, fields = [ "foo" ] },
{ version = 28, fields = [ "foo" ] },
{ version = 29, fields = [ "foo" ] },
{ version = 30, fields = [ "foo" ] },
{ version = 31, fields = [ "foo" ] },
{ version = 32, fields = [ "foo" ] },
{ version = 33, fields = [ "foo" ] },
{ version = 34, fields = [ "foo" ] },
{ version = 35, fields = [ "foo" ] },
{ version = 36, fields = [ "foo" ] },
{ version = 37, fields = [ "foo" ] },
{ version = 38, fields = [ "foo" ] },
{ version = 39, fields = [ "foo" ] },
{ version = 40, fields = [ "foo" ] },
{ version = 41, fields = [ "foo" ] },
{ version = 42, fields = [ "foo" ] },
{ version = 43, fields = [ "foo" ] },
{ version = 44, fields = [ "foo" ] },
{ version = 45, fields = [ "foo" ] },
{ version = 46, fields = [ "foo" ] },
{ version = 47, fields = [ "foo" ] },
{ version = 48, fields = [ "foo" ] },
{ version = 49, fields = [ "foo" ] },
{ version = 50, fields = [ "foo" ] },
{ version = 51, fields = [ "foo" ] },
{ version = 52, fields = [ "foo" ] },
{ version = 53, fields = [ "foo" ] },
{ version = 54, fields = [ "foo" ] },
{ version = 55, fields = [ "foo" ] },
{ version = 56, fields = [ "foo" ] },
{ version = 57, fields = [ "foo" ] },
{ version = 58, fields = [ "foo" ] },
{ version = 59, fields = [ "foo" ] },
{ version = 60, fields = [ "foo" ] },
{ version = 61, fields = [ "foo" ] },
{ version = 62, fields = [ "foo" ] },
{ version = 63, fields = [ "foo" ] },
{ version = 64, fields = [ "foo" ] },
{ version = 65, fields = [ "foo" ] },
{ version = 66, fields = [ "foo" ] },
{ version = 67, fields = [ "foo" ] },
{ version = 68, fields = [ "foo" ] },
{ version = 69, fields = [ "foo" ] },
{ version = 70, fields = [ "foo" ] },
{ version = 71, fields = [ "foo" ] },
{ version = 72, fields = [ "foo" ] },
{ version = 73, fields = [ "foo" ] },
{ version = 74, fields = [ "foo" ] },
{ version = 75, fields = [ "foo" ] },
{ version = 76, fields = [ "foo" ] },
{ version = 77, fields = [ "foo" ] },
{ version = 78, fields = [ "foo" ] },
{ version = 79, fields = [ "foo" ] },
{ version = 80, fields = [ "foo" ] },
{ version = 81, fields = [ "foo" ] },
{ version = 82, fields = [ "foo" ] },
{ version = 83, fields = [ "foo" ] },
{ version = 84, fields = [ "foo" ] },
{ version = 85, fields = [ "foo" ] },
{ version = 86, fields = [ "foo" ] },
{ version = 87, fields = [ "foo" ] },
{ version = 88, fields = [ "foo" ] },
{ version = 89, fields = [ "foo" ] },
{ version = 90, fields = [ "foo" ] },
{ version = 91, fields = [ "foo" ] },
{ version = 92, fields = [ "foo" ] },
{ version = 93, fields = [ "foo" ] },
{ version = 94, fields = [ "foo" ] },
{ version = 95, fields = [ "foo" ] },
{ version = 96, fields = [ "foo" ] },
{ version = 97, fields = [ "foo" ] },
{ version = 98, fields = [ "foo" ] },
{ version = 99, fields = [ "foo" ] },
{ version = 100, fields = [ "foo" ] },
{ version = 101, fields = [ "foo" ] },
{ version = 102, fields = [ "foo" ] },
{ version = 103, fields = [ "foo" ] },
{ version = 104, fields = [ "foo" ] },
{ version = 105, fields = [ "foo" ] },
{ version = 106, fields = [ "foo" ] },
{ version = 107, fields = [ "foo" ] },
{ version = 108, fields = [ "foo" ] },
{ version = 109, fields = [ "foo" ] },
{ version = 110, fields = [ "foo" ] },
{ version = 111, fields = [ "foo" ] },
{ version = 112, fields = [ "foo" ] },
{ version = 113, fields = [ "foo" ] },
{ version = 114, fields = [ "foo" ] },
{ version = 115, fields = [ "foo" ] },
{ version = 116, fields = [ "foo" ] },
{ version = 117, fields = [ "foo" ] },
{ version = 118, fields = [ "foo" ] },
{ version = 119, fields = [ "foo" ] },
{ version = 120, fields = [ "foo" ] },
{ version = 121, fields = [ "foo" ] },
{ version = 122, fields = [ "foo" ] },
{ version = 123, fields = [ "foo" ] },
{ version = 124, fields = [ "foo" ] },
{ version = 125, fields = [ "foo" ] },
{ version = 126, fields = [ "foo" ] },
{ version = 127, fields = [ "foo" ] },
{ version = 128, fields = [ "foo" ] },
{ version = 129, fields = [ "foo" ] },
{ version = 130, fields = [ "foo" ] },
{ version = 131, fields = [ "foo" ] },
{ version = 132, fields = [ "foo" ] },
{ version = 133, fields = [ "foo" ] },
{ version = 134, fields = [ "foo" ] },
{ version = 135, fields = [ "foo" ] },
{ version = 136, fields = [ "foo" ] },
{ version = 137, fields = [ "foo" ] },
{ version = 138, fields = [ "foo" ] },
{ version = 139, fields = [ "foo" ] },
{ version = 140, fields = [ "foo" ] },
{ version = 141, fields = [ "foo" ] },
{ version = 142, fields = [ "foo" ] },
{ version = 143, fields = [ "foo" ] },
{ version = 144, fields = [ "foo" ] },
{ version = 145, fields = [ "foo" ] },
{ version = 146, fields = [ "foo" ] },
{ version = 147, fields = [ "foo" ] },
{ version = 148, fields = [ "foo" ] },
{ version = 149, fields = [ "foo" ] },
{ version = 150, fields = [ "foo" ] },
{ version = 151, fields = [ "foo" ] },
{ version = 152, fields = [ "foo" ] },
{ version = 153, fields = [ "foo" ] },
{ version = 154, fields = [ "foo" ] },
{ version = 155, fields = [ "foo" ] },
{ version = 156, fields = [ "foo" ] },
{ version = 157, fields = [ "foo" ] },
{ version = 158, fields = [ "foo" ] },
{ version = 159, fields = [ "foo" ] },
{ version = 160, fields = [ "foo" ] },
{ version = 161, fields = [ "foo" ] },
{ version = 162, fields = [ "foo" ] },
{ version = 163, fields = [ "foo" ] },
{ version = 164, fields = [ "foo" ] },
{ version = 165, fields = [ "foo" ] },
{ version = 166, fields = [ "foo" ] },
{ version = 167, fields = [ "foo" ] },
{ version = 168, fields = [ "foo" ] },
{ version = 169, fields = [ "foo" ] },
{ version = 170, fields = [ "foo" ] },
{ version = 171, fields = [ "foo" ] },
{ version = 172, fields = [ "foo" ] },
{ version = 173, fields = [ "foo" ] },
{ version = 174, fields = [ "foo" ] },
{ version = 175, fields = [ "foo" ] },
{ version = 176, fields = [ "foo" ] },
{ version = 177, fields = [ "foo" ] },
{ version = 178, fields = [ "foo" ] },
{ version = 179, fields = [ "foo" ] },
{ version = 180, fields = [ "foo" ] },
{ version = 181, fields = [ "foo" ] },
{ version = 182, fields = [ "foo" ] },
{ version = 183, fields = [ "foo" ] },
{ version = 184, fields = [ "foo" ] },
{ version = 185, fields = [ "foo" ] },
{ version = 186, fields = [ "foo" ] },
{ version = 187, fields = [ "foo" ] },
{ version = 188, fields = [ "foo" ] },
{ version = 189, fields = [ "foo" ] },
{ version = 190, fields = [ "foo" ] },
{ version = 191, fields = [ "foo" ] },
{ version = 192, fields = [ "foo" ] },
{ version = 193, fields = [ "foo" ] },
{ version = 194, fields = [ "foo" ] },
{ version = 195, fields = [ "foo" ] },
{ version = 196, fields = [ "foo" ] },
{ version = 197, fields = [ "foo" ] },
{ version = 198, fields = [ "foo" ] },
{ version = 199, fields = [ "foo" ] },
{ version = 200, fields = [ "foo" ] },
{ version = 201, fields = [ "foo" ] },
{ version = 202, fields = [ "foo" ] },
{ version = 203, fields = [ "foo" ] },
{ version = 204, fields = [ "foo" ] },
{ version = 205, fields = [ "foo" ] },
{ version = 206, fields = [ "foo" ] },
{ version = 207, fields = [ "foo" ] },
{ version = 208, fields = [ "foo" ] },
{ version = 209, fields = [ "foo" ] },
{ version = 210, fields = [ "foo" ] },
{ version = 211, fields = [ "foo" ] },
{ version = 212, fields = [ "foo" ] },
{ version = 213, fields = [ "foo" ] },
{ version = 214, fields = [ "foo" ] },
{ version = 215, fields = [ "foo" ] },
{ version = 216, fields = [ "foo" ] },
{ version = 217, fields = [ "foo" ] },
{ version = 218, fields = [ "foo" ] },
{ version = 219, fields = [ "foo" ] },
{ version = 220, fields = [ "foo" ] },
{ version = 221, fields = [ "foo" ] },
{ version = 222, fields = [ "foo" ] },
{ version = 223, fields = [ "foo" ] },
{ version = 224, fields = [ "foo" ] },
{ version = 225, fields = [ "foo" ] },
{ version = 226, fields = [ "foo" ] },
{ version = 227, fields = [ "foo" ] },
{ version = 228, fields = [ "foo" ] },
{ version = 229, fields = [ "foo" ] },
{ version = 230, fields = [ "foo" ] },
{ version = 231, fields = [ "foo" ] },
{ version = 232, fields = [ "foo" ] },
{ version = 233, fields = [ "foo" ] },
{ version = 234, fields = [ "foo" ] },
{ version = 235, fields = [ "foo" ] },
{ version = 236, fields = [ "foo" ] },
{ version = 237, fields = [ "foo" ] },
{ version = 238, fields = [ "foo" ] },
{ version = 239, fields = [ "foo" ] },
{ version = 240, fields = [ "foo" ] },
{ version = 241, fields = [ "foo" ] },
{ version = 242, fields = [ "foo" ] },
{ version = 243, fields = [ "foo" ] },
{ version = 244, fields = [ "foo" ] },
{ version = 245, fields = [ "foo" ] },
{ version = 246, fields = [ "foo" ] },
{ version = 247, fields = [ "foo" ] },
{ version = 248, fields = [ "foo" ] },
{ version = 249, fields = [ "foo" ] },
{ version = 250, fields = [ "foo" ] },
{ version = 251, fields = [ "foo" ] },
{ version = 252, fields = [ "foo" ] },
{ version = 253, fields = [ "foo" ] },
{ version = 254, fields = [ "foo" ] },
{ version = 255, fields = [ "foo" ] },
{ version = 255, fields = [ "foo" ] },
]
[[metrics]]
name = "metric"
description = "some metric"
datum_type = "u8"
units = "count"
versions = [
{ added_in = 1, fields = [] },
]
[fields.foo]
type = "string"
description = "a field"
"#;
load_schema(contents).unwrap();
}
thread 'ir::tests::way_too_many_target_versions' (941567) panicked at /rustc/8bab26f4f68e0e26f0bb7960be334d5b520ea452/library/core/src/iter/range.rs:438:1:
attempt to add with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
A possible solution could be to add a explicit upper bound of 255 fields:
let mut target_fields_by_version = BTreeMap::new();
if self.target.versions.len() > 255 {
return Err(MetricsError::SchemaDefinition(format!(
"Target '{}' versions can only contain 255 versions (found {})",
target_name, self.target.versions.len(),
)));
}
// We know that it is at most 255
let upper_bound = self.target.versions.len() as u8;
for (expected_version, target_fields) in
(1u8..upper_bound).zip(self.target.versions.iter())
{
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in oximeter/schema/src/ir.rs at the target-version parsing and its zip with 1u8..; run the supplied way_too_many_target_versions reproducer with overflow checks enabled. Add coverage for the upper version limit and ensure parsing reports a sensible error rather than panicking or accepting invalid version sequences.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100