#1078049 unattended-upgrades: whitelist not working

#1078049#5
Date:
2024-08-06 10:15:14 UTC
From:
To:
Dear Maintainer,

I need to enable automatic upgrades only for few selected packages on some servers.
As documented Unattended-Upgrade::Package-Whitelist do this, I tried but didn't worked.
From a search I found an issue open on upstream where whitelist is not working as documented:
https://github.com/mvo5/unattended-upgrades/issues/293
I tried the workaround mentioned of also blacklist all:
Unattended-Upgrade::Package-Blacklist { ".*" };
But didn't worked, mark a blacklisted also the one in whitelist.
I did some other tests and search but I'm unable to found a workaround working.

#1078049#10
Date:
2024-08-06 11:42:07 UTC
From:
To:
Tried also on Debian 11 with unattended-upgrades 2.8, and have the same
issue.

Tried also on Debian 10 with unattended-upgrades 1.11.2, whitelist is
correctly working and without needs of blacklist all (which is perhaps
necessary in intermediate versions)

#1078049#23
Date:
2026-09-17 13:18:06 UTC
From:
To:
The cause is an operator precedence bug in calculate_upgradable_pkgs():
"and" binds tighter than "or", so the condition

     if (pkg.is_upgradable or candidate_version_changed(pkg)
        and is_pkgname_in_whitelist(pkg.name, cache.whitelist)):

is evaluated as "pkg.is_upgradable or (candidate_version_changed(pkg)
and is_pkgname_in_whitelist(...))". Every upgradable package satisfies
the first operand, so the whitelist is never consulted.

It was introduced upstream in commit 4d0c9cd, first released in 1.16
(October 2019), which is why 1.11.2 in Debian 10 is the last version
where the whitelist works: bullseye, bookworm and trixie are all
affected, as is the current upstream 2.13.

Fix and regression test proposed upstream:
https://github.com/mvo5/unattended-upgrades/pull/412
--- a/unattended-upgrade +++ b/unattended-upgrade @@ -2079,8 +2079,8 @@ def calculate_upgradable_pkgs(cache,   # type: UnattendedUpgradesCache                  getattr(pkg, "candidate", pkg.name),                  getattr(pkg.candidate, "origins", []))) -        if (pkg.is_upgradable or candidate_version_changed(pkg) -           and is_pkgname_in_whitelist(pkg.name, cache.whitelist)): +        if ((pkg.is_upgradable or candidate_version_changed(pkg)) +                and is_pkgname_in_whitelist(pkg.name, cache.whitelist)):              try:                  ver_in_allowed_origin(pkg, cache.allowed_origins)              except NoAllowedOriginError: