United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6332120 : File.deleteOnExit() with long file name causes buffer overflow

Details
Type:
Bug
Submit Date:
2005-10-04
Status:
Resolved
Updated Date:
2014-02-27
Project Name:
JDK
Resolved Date:
2006-08-03
Component:
core-libs
OS:
linux
Sub-Component:
java.io
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.2
Fixed Versions:
5.0u10 (b01)

Related Reports
Backport:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.5.0_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.12-1-K7 (on Debian Sarge)

EXTRA RELEVANT SYSTEM CONFIGURATION :
(none)

A DESCRIPTION OF THE PROBLEM :
Summary:

A deleteOnFile() invocation against the java.io.File object that stores a file name that could be longer than 4096 bytes (equal to PATH_MAX ??) when it gets decoded to the filesystem's encoding, causes severe memory corruption on Java VM termination, which leads to a bus error, or a segmentation fault. You can reproduce the exact problem with the attached code.

Technical Detail:

As far as I can tell from the result of reverse-engineering (I did not ever access to the source code), deleteOnExit() internally allocates the following structure by malloc() C-library function, fills the content of "buf" field with strcpy() ing the file name, and builds a linked list to use it in "onExit" handler:

struct OnExitHandler {
    struct OnExitHandler *nextHandler;
    void(*callback)(void *param);
    char buf[4096];
}

If this is the case, a buffer overflow that eventually induces a heap corruption can occur if the name of the file being associated to the structure is long enough to exceed the size of buf[] field. Since the structure is allocated in its exact size and the implementation of malloc() used here is publicly available, this flaw is easily exploitable to gain a shell, etc.

IMPACT:

Any program that takes an arbitrary file name from the user input to finally destroy it with deleteOnExit() is extremely vulnerable. For instance, an attacker can submit a malicious request to  a web application that stores uploaded files to a temporary directory with the same file names given in the request.




STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile & run the attached code.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
(None happens)
ACTUAL -
(Received SIGABRT signal)


ERROR MESSAGES/STACK TRACES THAT OCCUR :
*** glibc detected *** free(): invalid next size (normal): 0x080c8038 ***
Aborted


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.File;

public class J2SEVulnerabilityTest
{
	private static final int PATH_MAX = 4096;

	private static String generateArbitraryLengthOfString(int n) {
		StringBuffer buf = new StringBuffer(n);
		while (--n >= 0) {
			buf.append('#');
		}
		return buf.toString();
	}

	public static void main(String[] args) {
		File f = new File(generateArbitraryLengthOfString(PATH_MAX + 512));
		f.deleteOnExit();
	}
}

---------- END SOURCE ----------

                                    

Comments
EVALUATION

This is a 1.4.2 only issue now.
                                     
2005-10-07
EVALUATION

DeleteOnExitTest.java can still crash JVMs on 1.4.2_11 and 1.5.0_u6, on Solaris and Linux.
                                     
2006-05-12



Hardware and Software, Engineered to Work Together