cryptomator / dokany-nio-adapter

Dokany-based adapter to provide directory contents specified by a java.nio.file.Path (via dokan-java)
GNU Affero General Public License v3.0
14 stars 4 forks source link

findFiles() / findFilesWithPattern: Invalid Memory Access #12

Closed infeo closed 5 years ago

infeo commented 5 years ago

Basic Info

OS: Windows 10 Pro Ver 1809 Dokany-Version: 1.2.0.1000 Adapter-Version: commit e3d89f55c5f140599730ba1234d0e3e96228eef8

Description

While browsing through a mounted Volume with a lot of files and folders, sometimes a InvalidMemoryException is thrown during listing the directory content:

15:37:10:292 [Thread-106394] TRACE org.cryptomator.frontend.dokany.ReadWriteAdapter - (15680) findFilesWithPattern(): found file abc.ESN
15:37:10:292 [Thread-106394] TRACE org.cryptomator.frontend.dokany.ReadWriteAdapter - (15680) findFilesWithPattern(): found file bbb.ESN
15:37:10:292 [Thread-106394] TRACE org.cryptomator.frontend.dokany.ReadWriteAdapter - (15680) findFilesWithPattern(): found file ccc.ESN
15:37:10:292 [Thread-106394] ERROR org.cryptomator.frontend.dokany.ReadWriteAdapter - (15680) Error filling Win32FindData with file ccc.ESN. Occurred error is {}
15:37:10:292 [Thread-106394] ERROR org.cryptomator.frontend.dokany.ReadWriteAdapter - (15680) findFilesWithPattern(): Stacktrace:
java.lang.Error: Invalid memory access
    at com.sun.jna.Native.invokeVoid(Native Method)
    at com.sun.jna.Function.invoke(Function.java:414)
    at com.sun.jna.Function.invoke(Function.java:360)
    at com.sun.jna.Function.invoke(Function.java:314)
    at com.sun.jna.CallbackReference$NativeFunctionHandler.invoke(CallbackReference.java:679)
    at com.sun.proxy.$Proxy2.fillWin32FindData(Unknown Source)
    at org.cryptomator.frontend.dokany.ReadWriteAdapter.lambda$findFilesWithPattern$1(ReadWriteAdapter.java:542)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:430)
    at org.cryptomator.frontend.dokany.ReadWriteAdapter.findFilesWithPattern(ReadWriteAdapter.java:538)
    at com.dokany.java.DokanyOperationsProxy$FindFilesWithPatternProxy.callback(DokanyOperationsProxy.java:112)
    at jdk.internal.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback(CallbackReference.java:520)
    at com.sun.jna.CallbackReference$DefaultCallbackProxy.callback(CallbackReference.java:551)

I could caused this by rapidly switching between directories with ~400 files each.

The code where it is thrown is: https://github.com/cryptomator/dokany-nio-adapter/blob/e3d89f55c5f140599730ba1234d0e3e96228eef8/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java#L538-L549

overheadhunter commented 5 years ago

The cause is probably outside of the Java code, since it is (theoretically) impossible to access unallocated memory inside of Java. Therefore it is hard to tell what is happening without knowing the implementation of fillWin32FindData.

infeo commented 5 years ago

Maybe it is a bad initialization? The function takes a WIN32_FIND_DATA structure as input, which consists also of two Arrays. Currently the size of one of those arrays depends on the length of the filename, but in default constructors and the Windows documentation it is always initialized as an array of fixed size.

https://github.com/cryptomator/dokany-nio-adapter/blob/e3d89f55c5f140599730ba1234d0e3e96228eef8/src/main/java/com/dokany/java/structure/FullFileInfo.java#L58-L63