chore: remove unused runtime packages (libgcrypt, util-linux family, gzip, cracklib)#196
Open
jmromeroes wants to merge 2 commits into
Open
chore: remove unused runtime packages (libgcrypt, util-linux family, gzip, cracklib)#196jmromeroes wants to merge 2 commits into
jmromeroes wants to merge 2 commits into
Conversation
Adds libgcrypt to the existing microdnf remove list. Verified via `readelf -d` across all 951 ELF files in the built image: 0 NEEDED entries for libgcrypt.so. IQ Server (Java) uses BouncyCastle FIPS via JSSE for all cryptographic operations, not libgcrypt. libgcrypt is present only as a transitive install-time dep of systemd-libs, which is itself already removed via the rpm -e --nodeps step earlier in this block. Since systemd-libs is gone before microdnf remove runs, libgcrypt has no remaining declared requirer — microdnf's depsolver removes it cleanly. Validated on Dockerfile.slim (UBI 9.6 / IQ 1.204.2-01): - /lib64/libgcrypt* absent after build - Critical binaries (curl, ssh, git, sed, bash) all load without errors - IQ Server boots, Dropwizard framework serves APIs - Basic auth (admin:admin123) accepted - /rest/user/session returns HTTP 200 - /assets/index.html returns HTTP 200 - git ls-remote https://github.com/octocat/Hello-World.git succeeds (returns commit SHA — proves libcurl+OpenSSL+zlib+crypto stack functional) - ssh git@github.com completes ED25519 host key exchange (proves openssh client + OpenSSL crypto stack functional) Eliminates 2 CVEs from the build-stage scan: CVE-2026-41989 (libgcrypt ECDH heap overflow via gcry_pk_decrypt) CVE-2026-41990 (libgcrypt Dilithium signing bounds check) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eliminates CVEs by removing packages that have no runtime consumers, per Ross's feedback rejecting the gzip waiver and suggesting util-linux via rpm -e --nodeps with a /sbin/nologin symlink stand-in. Runtime verification: - Zero binaries in the image link libblkid/libmount/libsmartcols/libuuid/ libfdisk after removal (verified via readelf -d across all ELF files) - No runtime reference to gzip/gunzip in start.sh or the IQ Server bundle - ssh, ssh-keygen, git-over-https, and git-over-ssh all continue to work despite openssh's declared RPM file-dep on /sbin/nologin (a symlink to /bin/false substitutes with identical exit behavior) - Server boots and admin auth API responds correctly Ordering: microdnf remove runs first for the packages it can cleanly resolve, then rpm -e --nodeps removes the util-linux family (breaking openssh's file-dep), then a final rpm -e removes rpm/rpm-libs plus libarchive/libxml2/sqlite-libs/xz-libs/bzip2-libs which rpm itself depends on until it exits.
Contributor
|
@jmromeroes I also believe we can remove |
rpokorny
approved these changes
Jul 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Eliminates CVEs from packages that have zero runtime consumers in the image, following Ross's Slack guidance.
Two commits, each independently reviewable:
chore: remove libgcrypt from runtime image— libgcrypt has 0 NEEDED entries across all 951 ELF files in the image (Java uses BouncyCastle FIPS via JSSE, not libgcrypt). Added to the existingmicrodnf removelist; systemd-libs (removed viarpm -e --nodepsearlier in the same block) was the only reason libgcrypt was pulled in.chore: remove util-linux family + gzip from runtime image— 10 additional packages that have no runtime consumers:util-linux,util-linux-core,libblkid,libmount,libsmartcols,libuuid,libfdisk— all reported against the same CVEs by the scanner even though the vuln is in libblkid.cracklib,cracklib-dicts,gzip— transitively pulled in bypam(which is already removed viarpm -e --nodepsin the current block). Ross rejected the gzip waiver noting gzip could be removed instead.How commit 2 works
opensshdeclares an RPM file-dep on/sbin/nologin(owned byutil-linux), so a straightmicrodnf removerefuses. We userpm -e --nodepsto break that declared dep and substitute/sbin/nologinwith a symlink to/bin/false—coreutils-single(still in the image) provides/bin/falsewith identical exit behavior, so any/etc/passwdshell entries referencing nologin still resolve.The 5-step removal ordering in commit 2 is dictated by rpm's own runtime deps — the
rpmbinary dynamically links againstlibsqlite3,liblzma,libbz2,libarchive(vialibrpm.so), and transitivelylibxml2:rpm -e --nodepsfor the existing pre-microdnf list (unchanged):gawk libfido2 systemd-libs p11-kit p11-kit-trust libtasn1 pam libpwquality expatmicrodnf removefor everything the depsolver can cleanly resolve — this step addscracklib cracklib-dicts gzip; removeslibxml2/libarchive/sqlite-libs/xz-libs/bzip2-libs/rpm/rpm-libsfrom this step sorpmstays alive one step longerrpm -e --nodeps util-linux util-linux-core libblkid libmount libsmartcols libuuid libfdisk(breaks openssh's declared file-dep on/sbin/nologin)ln -sf /bin/false /sbin/nologinrpm -e --nodeps rpm rpm-libs libarchive libxml2 sqlite-libs xz-libs bzip2-libs— rpm has already loaded its libs at process start, so it can remove them from the same transactionVerification
Static analysis
libblkid,libmount,libsmartcols,libuuid,libfdisk,libsqlite3,liblzma,libbz2,libgcryptacross all ELF files in the built image (verified viareadelf -d).gziporgunzipinstart.shor the IQ Server bundle./var/lib/rpm/rpmdb.sqliteconfirms all removed packages are absent from theNametable — the Sonatype scanner reads this DB to build its inventory.Full end-to-end runtime test (real license, real APIs)
Started the built slim image with the
sonatype-lc-only.liclicense, then exercised the complete IQ Server stack:POST /api/v2/product/licensehealth=healthylog4j-core@2.14.0ssh -V+ssh-keygen -t ed25519Log analysis
Full log scan surfaced 25 WARN/ERROR lines. All fall into one of these expected categories, none related to package removals:
CVEs eliminated (from open waiver requests)
libgcryptutil-linuxfamily (×7)CVE-2026-13595on each subpackagegzipCVE-2026-41991(Ross-rejected waiver)Waiver requests for these CVEs have been withdrawn via API.
Testing done
Built and ran
Dockerfile.slimlocally viadocker build --platform linux/amd64. Same removal pattern applied identically toDockerfileandDockerfile.rh.🤖 Generated with Claude Code