Skip to content

Commit 6a1e045

Browse files
karesclaude
andcommitted
[refactor] overflow protection in MemBIO buffer reallocation
The old realloc() doubled buffer.length without overflow checks, which could wrap int to a negative value when the buffer exceeded ~1 billion bytes. The write() loop condition (wpointer + len) could also overflow, skipping the realloc entirely. Replace realloc() with growTo(minCapacity) using long arithmetic to prevent int overflow when doubling, capped at Integer.MAX_VALUE - 8. Compute required capacity in write() with long to detect overflow before growing. Guard against non-positive len, matching C OpenSSL's mem_write. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e003210 commit 6a1e045

1 file changed

Lines changed: 19 additions & 5 deletions

File tree

src/main/java/org/jruby/ext/openssl/impl/MemBIO.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,21 @@
3434
* @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
3535
*/
3636
public class MemBIO extends BIO {
37+
// Some VMs reserve header words in arrays; this is the largest safe allocation.
38+
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
39+
3740
private byte[] buffer = new byte[1024];
3841
private int wpointer = 0;
3942
private int rpointer = 0;
4043
private int slen = 0;
41-
42-
private void realloc() {
43-
byte[] newBuffer = new byte[buffer.length*2];
44+
45+
private void growTo(int minCapacity) {
46+
int newLen = buffer.length;
47+
while (newLen < minCapacity) {
48+
// Use long arithmetic to avoid overflow when doubling
49+
newLen = (int) Math.min((long) newLen * 2, MAX_BUFFER_SIZE);
50+
}
51+
byte[] newBuffer = new byte[newLen];
4452
System.arraycopy(buffer, 0, newBuffer, 0, wpointer);
4553
buffer = newBuffer;
4654
}
@@ -75,8 +83,14 @@ public int read(byte[] in, int index, int len) throws IOException {
7583

7684
@Override
7785
public int write(byte[] out, int offset, int len) throws IOException {
78-
while(wpointer + len > buffer.length) {
79-
realloc();
86+
if (len <= 0) return 0; // matches C OpenSSL mem_write behavior
87+
// Use long to detect int overflow in the addition
88+
long required = (long) wpointer + len;
89+
if (required > MAX_BUFFER_SIZE) {
90+
throw new IOException("MemBIO buffer size limit exceeded");
91+
}
92+
if (required > buffer.length) {
93+
growTo((int) required);
8094
}
8195

8296
System.arraycopy(out, offset, buffer, wpointer, len);

0 commit comments

Comments
 (0)