Skip to content

PreparedStatement execution with java.io.tmpdir pointing to a directory symlink results in FileAlreadyExistsException #3510

@aikebah

Description

@aikebah

On OWASP DependencyCheck there was a report on a FileAlreadyExistsException that originates in the H2 database library.

The codebase of H2 appears to be unable to handle a prepared statement call with the java.io.tmpdir property pointing to a symlink that is pointing to a directory.

The (truncated) root stacktrace:

Caused by: java.nio.file.FileAlreadyExistsException: /Users/aikebah/linktemp
    at sun.nio.fs.UnixException.translateToIOException (UnixException.java:94)
    at sun.nio.fs.UnixException.rethrowAsIOException (UnixException.java:106)
    at sun.nio.fs.UnixException.rethrowAsIOException (UnixException.java:111)
    at sun.nio.fs.UnixFileSystemProvider.createDirectory (UnixFileSystemProvider.java:397)
    at java.nio.file.Files.createDirectory (Files.java:700)
    at java.nio.file.Files.createAndCheckIsDirectory (Files.java:807)
    at java.nio.file.Files.createDirectories (Files.java:753)
    at org.h2.store.fs.disk.FilePathDisk.createTempFile (FilePathDisk.java:435)
    at org.h2.store.fs.FileUtils.createTempFile (FileUtils.java:404)
    at org.h2.mvstore.db.MVTempResult.<init> (MVTempResult.java:178)
    at org.h2.mvstore.db.MVPlainTempResult.<init> (MVPlainTempResult.java:69)
    at org.h2.mvstore.db.MVTempResult.of (MVTempResult.java:82)
    at org.h2.result.LocalResult.createExternalResult (LocalResult.java:382)
    at org.h2.result.LocalResult.addRowsToDisk (LocalResult.java:441)
    at org.h2.result.LocalResult.addRowInternal (LocalResult.java:434)
    at org.h2.result.LocalResult.addRowForTable (LocalResult.java:398)
    at org.h2.command.dml.SetClauseList.prepareUpdate (SetClauseList.java:166)
    at org.h2.command.dml.Update.update (Update.java:88)
    at org.h2.command.dml.DataChangeStatement.update (DataChangeStatement.java:61)
    at org.h2.command.CommandContainer.update (CommandContainer.java:174)
    at org.h2.command.Command.executeUpdate (Command.java:252)
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal (JdbcPreparedStatement.java:209)
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdate (JdbcPreparedStatement.java:169)
    at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate (DelegatingPreparedStatement.java:136)
    at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate (DelegatingPreparedStatement.java:136)
    at org.owasp.dependencycheck.data.nvdcve.CveDB.cleanupDatabase (CveDB.java:1265)

Looks to me like h2 should first check whether the location exists (and is either a directory or a symlink pointing to a directory) before trying to create it.

See also https://bugs.openjdk.java.net/browse/JDK-8130464 where the JVM maintainers say that 'Files#createDirectories' works as designed, so they don't consider the FileAlreadyExistsException an error in the JVM.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions