Problem
load_platform_root_certificates_inner (lib/saluki-tls/src/lib.rs) already filters out NotFound IO errors when walking the platform cert store, and tolerates individual malformed PEM files as long as at least one cert loads successfully. However, PermissionDenied IO errors are not filtered — they are retained in result.errors.
If a host has only unreadable cert files in its cert dir (e.g. sendmail.pem or localhost.crt with mode 0600), all of result.certs is empty, the function returns an error, and ADP crashes during bootstrap.
On hosts where ADP is disabled, this crash feeds into #2105: the process never reaches the enablement check, systemd marks the unit failed, and restart-loops it.
Current behavior
// lib/saluki-tls/src/lib.rs ~568
result.errors.retain(|err| {
!matches!(
&err.kind,
rustls_native_certs::ErrorKind::Io { inner, .. }
if inner.kind() == std::io::ErrorKind::NotFound,
)
});
PermissionDenied passes the retain filter and is left in result.errors. If no certs were loaded (added == 0), the function errors out.
Expected behavior
Unreadable cert files should be treated similarly to missing files: logged at debug level and skipped, rather than failing the entire bootstrap. Either:
- Also filter
PermissionDenied from result.errors, or
- Only fail when
result.errors contains errors that are not IO errors (i.e., actual parse/crypto errors)
A test covering the permission-denied case should be added alongside the fix (similar to partial_load_succeeds.rs).
Notes
- Reproduced from support tickets 2928863 and 2900922 (resolution in both: redirect
ssl_cert_dir to an empty directory, or chmod a+r the offending cert).
rustls-native-certs 0.8.4 supports partial loading; this fix stays within existing patterns.
Problem
load_platform_root_certificates_inner(lib/saluki-tls/src/lib.rs) already filters outNotFoundIO errors when walking the platform cert store, and tolerates individual malformed PEM files as long as at least one cert loads successfully. However,PermissionDeniedIO errors are not filtered — they are retained inresult.errors.If a host has only unreadable cert files in its cert dir (e.g.
sendmail.pemorlocalhost.crtwith mode0600), all ofresult.certsis empty, the function returns an error, and ADP crashes during bootstrap.On hosts where ADP is disabled, this crash feeds into #2105: the process never reaches the enablement check, systemd marks the unit failed, and restart-loops it.
Current behavior
PermissionDeniedpasses the retain filter and is left inresult.errors. If no certs were loaded (added == 0), the function errors out.Expected behavior
Unreadable cert files should be treated similarly to missing files: logged at debug level and skipped, rather than failing the entire bootstrap. Either:
PermissionDeniedfromresult.errors, orresult.errorscontains errors that are not IO errors (i.e., actual parse/crypto errors)A test covering the permission-denied case should be added alongside the fix (similar to
partial_load_succeeds.rs).Notes
ssl_cert_dirto an empty directory, orchmod a+rthe offending cert).rustls-native-certs0.8.4 supports partial loading; this fix stays within existing patterns.