3

As far as I understand, Java Strings are just an array of characters, with the maximum length being an integer value. If I understand this answer correctly, it is possible to cause an overflow with a String - albeit in "unusual circumstances".

Since Java Strings are based on char arrays and Java automatically checks array bounds, buffer overflows are only possible in unusual scenarios:

  1. If you call native code via JNI
  2. In the JVM itself (usually written in C++)
  3. The interpreter or JIT compiler does not work correctly (Java bytecode mandated bounds checks)

Correct me if I'm wrong, but I believe this means that you can write outside the bounds of the array, without triggering the ArrayIndexOutOfBounds (or similar) exception.

I've encountered issues in C++ with buffer overflows, and I can find plenty of advice about other languages, but none specifically answering what would happen if you caused a buffer overflow with a String (or any other array type) in Java.

I know that Java Strings are bounds-checked, and can't be overflowed by native Java code alone (unless issues are present in the compiler or JVM, as per points 2 and 3 above), but the first point implies that it is technically possible to get a char[] into an... undesirable position.

Given this, I have two specific questions about the behaviour of such issues in Java, assuming the above is correct:

  1. If a String can overflow, what happens when it does?
  2. What would the implications of this behaviour be?

Thanks in advance.

  • 1
    You can't overflow a String using Java code only. Strings are immutable. – Olivier Mar 19 '20 at 11:08
  • 1
    Even the internal representation differs depending on [version and runtime flags](https://stackoverflow.com/questions/9699071/what-is-the-javas-internal-represention-for-string-modified-utf-8-utf-16). Java gets rid of the "normal" buffer overflows that are present in some languages, so if you manage to get one it can be very hard to determine what exactly might happen. In most cases probably (semi-educated guess) a hard error instead of an easily exploitable security flaw. – Kayaman Mar 19 '20 at 11:14

2 Answers2

4

To answer you first question, I had the luck of actually causing a error of such, and the execution just stopped throwing one of these errors:

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

So that was my case, I don't know if that represents a security problem as buffer overflow in C and C++.

Mihai
  • 66
  • 3
  • 1
    A string/char[] of size Integer.MAX_VALUE will need approx. 8.6GB of RAM to fully populate, given 2-bits per char. If you assign 9GB+ of RAM to the JVM, you should be able to put more data into the array - add ``-Xmx9G`` to your launch parameters. I think the default is 1GB or so? – Alan Lovell Mar 19 '20 at 11:18
0

A String in Java is immutable, so once created there is no writing to the underlying array of char or array of byte (it depends on the Java version and contents of the String whether one or the other is used). Ok, using JNI could circumvent that, but with pure Java, it is impossible to leave the bounds of the array without causing an ArrayOutOfBoundsException or alike.

The only way to cause a kind of an overflow in the context of String handling would be to create a new String that is too long. Make sure that your JVM will have enough heap (around 36 GB), create a char array of Integer.MAX_VALUE - 1, populate that appropriately, call new String( byte [] ) with that array, and then execute

var string = string.concat( new String( array ) );

But the result is just an exception telling you that it was attempted to create a too large array.

tquadrat
  • 3,033
  • 1
  • 16
  • 29