Skip to content

Commit 919b1d3

Browse files
committed
Fix: Overflow when parsing large version numbers in notus
Before we used u32 for parsing version numbers within the version comparison algorithm. Now it is checked if the version part is a number, then leading zeroes are removed and both strings are then checked.
1 parent e6abbc2 commit 919b1d3

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

rust/src/notus/packages/mod.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,27 @@ impl PartialOrd for PackageVersion {
8787
}
8888

8989
// check if parts are numbers
90-
match (a_part.parse::<u32>(), b_part.parse::<u32>()) {
91-
(Ok(a), Ok(b)) => return a.partial_cmp(&b),
92-
(Ok(_), _) => return Some(Ordering::Greater),
93-
(_, Ok(_)) => return Some(Ordering::Less),
90+
match (
91+
a_part.chars().all(char::is_numeric),
92+
b_part.chars().all(char::is_numeric),
93+
) {
94+
(true, true) => {
95+
// Remove leading zeros
96+
let a_trimmed = a_part.trim_start_matches('0');
97+
let b_trimmed = b_part.trim_start_matches('0');
98+
// Compare the length of the numbers
99+
match a_trimmed.len().cmp(&b_trimmed.len()) {
100+
// If the length is the same, compare the numbers
101+
Ordering::Equal => match a_trimmed.cmp(b_trimmed) {
102+
// After trimming zeroes, the numbers could be the same
103+
Ordering::Equal => continue,
104+
ord => return Some(ord),
105+
},
106+
ord => return Some(ord),
107+
}
108+
}
109+
(true, _) => return Some(Ordering::Greater),
110+
(_, true) => return Some(Ordering::Less),
94111
_ => (),
95112
}
96113

rust/src/notus/packages/rpm.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,39 @@ mod rpm_tests {
446446
full_version: "1.2.3-5.x86_64".to_string(),
447447
};
448448
assert!(package1 < package2);
449+
450+
let package1 = Rpm {
451+
name: "vim-minimal".to_string(),
452+
epoch: 0,
453+
version: PackageVersion("9.0.2092".to_string()),
454+
release: PackageVersion("8.oe2403".to_string()),
455+
arch: "x86_64".to_string(),
456+
full_name: "vim-minimal-9.0.2092-8.oe2403.x86_64".to_string(),
457+
full_version: "9.0.2092-8.oe2403.x86_64".to_string(),
458+
};
459+
460+
let package2 = Rpm {
461+
name: "vim-minimal".to_string(),
462+
epoch: 0,
463+
version: PackageVersion("4294967296.0.2092".to_string()),
464+
release: PackageVersion("8.oe2403".to_string()),
465+
arch: "x86_64".to_string(),
466+
full_name: "vim-minimal-4294967296.0.2092-8.oe2403.x86_64".to_string(),
467+
full_version: "4294967296.0.2092-8.oe2403.x86_64".to_string(),
468+
};
469+
assert!(package1 < package2);
470+
471+
let package2 = Rpm {
472+
name: "vim-minimal".to_string(),
473+
epoch: 0,
474+
version: PackageVersion("429496729542949672954294967295.0.2092".to_string()),
475+
release: PackageVersion("8.oe2403".to_string()),
476+
arch: "x86_64".to_string(),
477+
full_name: "vim-minimal-429496729542949672954294967295.0.2092-8.oe2403.x86_64"
478+
.to_string(),
479+
full_version: "429496729542949672954294967295.0.2092-8.oe2403.x86_64".to_string(),
480+
};
481+
assert!(package1 < package2);
449482
}
450483

451484
#[test]

0 commit comments

Comments
 (0)