SerCeMan / jnr-fuse

FUSE implementation in Java using Java Native Runtime (JNR)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

FileStat contains garbage from uninitialized memory in getattr

tobihagemann opened this issue · comments

In Cryptomator, we had this weirdest bug when using FUSE on macOS for the longest time. See issues cryptomator/cryptomator#659, cryptomator/cryptomator#705, cryptomator/cryptomator#742.

I tried to put down my findings in the actual repository of our FUSE library but was still completely clueless back then: cryptomator/fuse-nio-adapter#19

We finally found the issue some days ago! In getattr(), sometimes the stat object is already filled with garbage. Here is an example, I put a conditional breakpoint when stat.st_flags.get() != 0.

getattr-stat

In most cases, the stat object is correctly only filled with nil values. Btw, this was our fix. We didn't notice this bug earlier because we were already overriding most of the values but overlooked the macOS specific ones. And st_flags caused these permission issues.

Is this something that should be fixed in jnr-fuse? Are these even garbage values? We had no idea that stat could already filled with "anything" and it caused us a lot of headache... who knows, maybe also others that are using this library?

Edit: We noticed this bug throughout several versions of macOS (I personally used High Sierra and Mojave) and osxfuse (from 3.7.1 to 3.8.2). In FUSE-NIO-Adapter, we're using jnr-fuse in version 0.5.2.1 (but I guess we also noticed this bug beginning with 0.5.1 so it's probably not a "new" bug).

Hi, @tobihagemann!

Thank you for the investigation, this is a really interesting finding! Did you figure out how to reproduce this issue reliably? I think it would be useful to use a version of osxfuse with debugging information to ensure that this problem is not caused by jnr-fuse or the JNR layer.

I wouldn't say I can reproduce it reliably but it's not too hard either. For example, I just used your MemoryFS and interacted with it a little.

TextEdit is kind of weird and I can't save at all (but not because of garbage values as far as I can tell, not sure what's wrong) but saving an Excel file immediately triggered the conditional breakpoint (I set one at MemoryFS.java#L254).

Just tried some more stuff and I can even reproduce the issue now just by calling:

echo "asd" > foo.txt

Not 100% every time but often enough. I guess you can use any application and interact with the volume somehow. You'll hit some garbage values eventually.

I must admit that I have no idea how to use osxfuse with debugging information. Or did you mean to use the mount option -d? Haha, about that... when using -d, I'm unable to reproduce the issue at all. That was also the thing that frustrated us. 😅

I have no idea if the issue is caused by jnr-fuse, the JNR layer, or osxfuse... I just can tell that the stat object is filled with garbage values when it shouldn't be.

Edit: Btw, I used new MemoryFS() and mounted that. Didn't see that it has its own main function where debug is enabled. I guess you wouldn't be able to reproduce the issue when you used that.

Maybe also good to know: While debugging this issue, I used bindfs to observe certain behavior with various mount options. I was never able to reproduce the issue with bindfs. That's why I kind of ruled osxfuse out as a cause of this issue. But I can't be absolutely certain.

I forgot to follow up on this issue. We fixed this quite some time ago, this is our solution: https://github.com/cryptomator/fuse-nio-adapter/blob/ae5594170a82765cbda604f9e61a0814482906b7/src/main/java/org/cryptomator/frontend/fuse/FileAttributesUtil.java#L74-L79

I don't know if this is something to be expected or not. Memory management is hard? 😉