- Generate the file:
$ awk 'BEGIN { for(c=0;c<10000000;c++) printf "<p>LOL</p>" }' > 100M.html
$ (for I in `seq 1 100`; do cat 100M.html; done) | pv | gzip -9 > 10G.boomgz
- Check it is indeed good:
| [477385324ns] Safepoint synchronization complete | |
| [479509579ns] Leaving safepoint | |
| [479511092ns] Disarming safepoint | |
| [479515701ns] Resuming GC threads | |
| [479517274ns] Unblocking thread 0x00007e5b24578ba0 [907803] | |
| [479518205ns] Unblocking thread 0x00007e5b245755d0 [907800] | |
| [479519849ns] Unblocking thread 0x00007e5b2457a590 [907804] | |
| [479520179ns] Unblocking thread 0x00007e5b24576580 [907801] | |
| [479521682ns] Unblocking thread 0x00007e5b2457cf00 [907806] | |
| [479522053ns] Safepoint "G1CollectForAllocation", Time since last: 465099860 ns, Reaching safepoint: 83448 ns, At safepoint: 2124165 ns, Leaving safepoint: 12073 ns, Total: 2219686 ns, Threads: 6 runnable, 19 total |
$ awk 'BEGIN { for(c=0;c<10000000;c++) printf "<p>LOL</p>" }' > 100M.html
$ (for I in `seq 1 100`; do cat 100M.html; done) | pv | gzip -9 > 10G.boomgz
DISCLAIMER #1: THIS GIST IS INFORMATIONAL ONLY AND NOT A COMPLETE SECURITY GUIDANCE. Use this data with care, and please recheck the commits if you want to cite them as the source.
DISCLAIMER #2: JDK MITIGATIONS ARE NOT THE WHOLE STORY. THE REAL FIX IS IN LOG4J, UPGRADE TO AT LEAST 2.15.0 OR SET log4j2.formatMsgNoLookups=true.
There might be more vectors than these mitigations cover. JDK mitigations shrink the attack surface, but they are not guaranteed to solve everything. I only checked this mitigates a few simple proof-of-concepts.
*TL;DR: Use JDK update releases that are less than 3 years old, and all known mitigations are there.
| # | |
| # A fatal error has been detected by the Java Runtime Environment: | |
| # | |
| # SIGSEGV (0xb) at pc=0x000000011c31e16d, pid=61939, tid=9987 | |
| # | |
| # JRE version: OpenJDK Runtime Environment (16.0) (fastdebug build 16-internal+0-adhoc.user924655.jdk) | |
| # Java VM: OpenJDK 64-Bit Server VM (fastdebug 16-internal+0-adhoc.user924655.jdk, mixed mode, sharing, tiered, compressed oops, shenandoah gc, bsd-amd64) | |
| # Problematic frame: | |
| # j java.lang.Class.getClassLoader0()Ljava/lang/ClassLoader;+0 java.base | |
| # |
| import java.lang.reflect.AccessibleObject; | |
| import java.lang.reflect.Field; | |
| public class Play { | |
| public static void main(String[] args) throws Exception { | |
| AddressExtractor ae = new AddressExtractor(); | |
| Field pvField = AddressExtractor.class.getDeclaredField("pointerValue"); | |
| Field type = Field.class.getDeclaredField("type"); | |
| type.setAccessible(true); | |
| type.set(pvField, Object.class); |
| $ cat Test.java | |
| public class Test { | |
| int t1() { | |
| int i1 = 1; | |
| int i2 = 1; | |
| return i1 + i2; | |
| } | |
| int t2() { | |
| final int i1 = 1; | |
| final int i2 = 1; |
| === x86_64: | |
| Linux reported RSS: 246.596 KB | |
| Total: reserved=1838633KB, committed=184453KB | |
| - Java Heap (reserved=524288KB, committed=25856KB) | |
| (mmap: reserved=524288KB, committed=25856KB) | |
| - Class (reserved=1113965KB, committed=73513KB) | |
| (classes #11360) | |
| ( instance classes #10643, array classes #717) |
| void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp) { | |
| assert(ShenandoahCASBarrier || ShenandoahLoadRefBarrier, "should be enabled"); | |
| // The below loads the mark word, checks if the lowest two bits are | |
| // set, and if so, clear the lowest two bits and copy the result | |
| // to dst. Otherwise it leaves dst alone. | |
| // Implementing this is surprisingly awkward. I do it here by: | |
| // - Inverting the mark word | |
| // - Test lowest two bits == 0 | |
| // - If so, set the lowest two bits | |
| // - Invert the result back, and copy to dst |
| Compiling 9228 files for BUILD_JDK | |
| c:\Work\jdk8u-jdk8u-dev\jdk\src\windows\classes\sun\awt\windows\WToolkit.java:843: error: cannot find symbol | |
| if (lge instanceof DisplayChangedListener) { | |
| ^ | |
| symbol: class DisplayChangedListener | |
| location: class WToolkit | |
| c:\Work\jdk8u-jdk8u-dev\jdk\src\windows\classes\sun\awt\windows\WToolkit.java:844: error: cannot find symbol | |
| ((DisplayChangedListener) lge).displayChanged(); | |
| ^ | |
| symbol: class DisplayChangedListener |
| From: <random Facebook person> | |
| Subject: Java sucks | |
| Hey, try to put 100M objects into arraylist, and see Java freezes for seconds! | |
| Q.E.D. | |
| Love and kisses, | |
| <random person you never knew> |