Repository navigation
Hardened native libraries extraction - #2971
Conversation
jaime-jmebot
left a comment
There was a problem hiding this comment.
Thanks for picking this up — the hardening looks solid: a fresh random directory per run, CREATE_NEW extraction, private permissions and the symlink/poisoned-file rejection all remove the predictable-path attack surface, and the new tests cover the fallback chain and concurrency well.
A few things worth a look (details inline):
- The noexec probe in
NativeLibraryExtraction.checkExecutable()may be a no-op on Linux — if so the retry-on-UnsatisfiedLinkErrorpath is doing the real work, and the noexec test would be skipped rather than exercising it. setExtractNativeLibraries(false)without a custom folder can no longer find pre-extracted natives, since the folder is now random each run.- Minor cleanups: name the retry bound so it can't drift from the root list, and drop
NativeLibraryLoader.isExtractingRequired()— this PR orphaned it (extraction no longer compares timestamps).
| for (AclEntry entry : view.getAcl()) { | ||
| if (entry.type() == AclEntryType.ALLOW && !entry.principal().equals(acl.get(0).principal())) { | ||
| throw new IOException("Cannot restrict native directory ACL: " + directory); | ||
| } | ||
| } |
There was a problem hiding this comment.
Worth double-checking this on Windows: both createTempDirectory(...) and setAcl(...) end up in SetFileSecurity(..., DACL_SECURITY_INFORMATION, ...), and the JDK never marks the DACL as protected (SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE)), so Windows is free to merge the parent's inheritable ACEs (SYSTEM, Administrators, and possibly the local Users group under %TEMP%) back into the ACL. If it does, getAcl() returns more than your single owner entry, this loop throws, and every extraction root gets rejected — natives would not load at all on Windows.
Did the new createsUniquePrivateDirectories test actually pass for you on Windows? If yes, please ignore me — I only had Linux available to reason from. If it does reproduce, relaxing this to reject only foreign entries that grant write/delete (rather than any foreign ALLOW) would keep most of the protection.
jaime-jmebot
left a comment
There was a problem hiding this comment.
Thanks for the quick turnaround — the earlier points all look addressed: extraction-disabled without a custom folder now fails explicitly (with a test), the retry bound is a named constant, isExtractingRequired() is gone, and the temp-folder lifetime is documented. The fallback chain and its tests read well.
- First: my noexec remark was wrong —
access(X_OK)does honourMS_NOEXECon Linux, socheckExecutable()is meaningful (details in the thread). Sorry for the detour. - One open question on the Windows ACL path, inline: if the OS re-merges inherited ACEs there, the check rejects every root and nothing loads. A quick confirmation that the new test ran on Windows would close it.
- Tiny leftover in
getJmeUserCacheFolder():Path base = null; if (base == null) {is always true, looks like a remnant of an earlier refactor.
Supersedes #2764