fix: report the source package's version, not only its name
`get_packages` named the Debian source package and never its version, so a
consumer was handed two numbers on different axes and no way to tell.
OSV states Debian ranges in *source* versions. libldb2 is
2:2.11.0+samba4.22.11+dfsg-… while its source, samba, is 2:4.22.11+dfsg-…;
comparing the first against a samba range is meaningless, and dpkg reads
ldb's 2.11.0 as older than the 2:4.17.4+dfsg-1 that fixed CVE-2022-44640.
Reporting the source without its version is worse than reporting neither,
because it looks usable.
Measured on three live Proxmox nodes: every one of their 2 349 packages
was in that state — 802 of 802, 774 of 774, 773 of 773 — while twenty
non-Proxmox hosts had both fields. It was not a parsing bug. The
dpkg-query format string never asked for ${source:Version}, so nothing
downstream could have recovered it.
Now asked for and reported, with the same fallback napalm-linux uses:
dpkg leaves the field empty when it equals Version, and an older dpkg
leaves it empty because it does not know the field at all. Neither may
produce a package without a coordinate.
tests/test_packages.py covers all of it, including that the *query* names
the field — the assertion that would have caught this.
This commit is contained in:
@@ -245,7 +245,8 @@ class ProxmoxSystemMixin:
|
||||
# Installed packages via SSH dpkg-query
|
||||
raw = self._exec_ssh_command(
|
||||
"dpkg-query -W -f="
|
||||
"'${Package}\\t${Version}\\t${db:Status-Status}\\t${Installed-Size}\\t${source:Package}\\n'"
|
||||
"'${Package}\\t${Version}\\t${db:Status-Status}\\t${Installed-Size}"
|
||||
"\\t${source:Package}\\t${source:Version}\\n'"
|
||||
" 2>/dev/null"
|
||||
)
|
||||
result: list[_JsonDict] = []
|
||||
@@ -260,6 +261,19 @@ class ProxmoxSystemMixin:
|
||||
# Debian source package (differs from the binary for split packages,
|
||||
# e.g. openssh-server → openssh). Needed for accurate OSV matching.
|
||||
source_package = parts[4] if len(parts) > 4 and parts[4] else name
|
||||
# And its version, which is a different number from this package's.
|
||||
#
|
||||
# OSV states Debian ranges in *source* versions, so a consumer given
|
||||
# the source package and only the binary version compares two
|
||||
# unrelated numbers: libldb2 is 2:2.11.0+samba4.22.11+dfsg-… while
|
||||
# its source, samba, is 2:4.22.11+dfsg-…. Reporting the source
|
||||
# without its version is worse than reporting neither, because it
|
||||
# looks usable. Every package on all three Proxmox nodes was in that
|
||||
# state — the format string never asked for the field.
|
||||
#
|
||||
# dpkg leaves it empty when it equals `Version`, and so does an
|
||||
# older dpkg that does not know the field at all.
|
||||
source_version = parts[5] if len(parts) > 5 and parts[5] else version
|
||||
if not name or status != "installed":
|
||||
continue
|
||||
size_bytes = int(size_kb) * 1024 if size_kb.isdigit() else 0
|
||||
@@ -271,6 +285,7 @@ class ProxmoxSystemMixin:
|
||||
"size": size_bytes,
|
||||
"source": "pve",
|
||||
"source_package": source_package,
|
||||
"source_version": source_version,
|
||||
"upgrade_version": upgradable.get(name, ""),
|
||||
})
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user