This project has moved and is read-only. For the latest updates, please go here.
4

Closed

Invalid characters encountered

description

Since openSUSE has switched to gcc5 with new libstdc++ ABI veracrypt doesn't work after compilation.
Because of the ABI change I need to recompile a dynamic linked veracrypt.
But when trying to mount a truecrypt file volume I get a message window, telling me only about "Invalid characters encountered."
I've tried to debug it and it seems to be fuse-related. So maybe not a compiler/libstdc++ problem, but a incompatibility with new fuse version 2.9.4?!
It would be helpful, if the message would tell more about the exact exception cause.
So, please have a look at.
Closed Mar 18, 2016 at 4:45 PM by idrassi

comments

Arlecchino wrote Jul 25, 2015 at 9:44 AM

I've to add... that sometimes instead of the "Invalid characters encountered" message I get a "fuse: bad mount point" message with a string that looks like there is some random/wrong memory access.

RussianNeuroMance wrote Sep 30, 2015 at 5:08 PM

Same issue with Kubuntu 15.10.

jenyay wrote Oct 24, 2015 at 6:52 PM

Same with Ubuntu 15.10

idrassi wrote Oct 26, 2015 at 11:09 PM

Thank you for these reports.

One key point is that the official VeraCrypt Linux binary works without any problem on the affected system. This means that the installed fuse can not be called from applications using the new libstdc++ ABI.

One solution would be to add -D_GLIBCXX_USE_CXX11_ABI=0 to VeraCrypt Makefile but this means that we can't use the system wxWidgets library and we must statically link against our own copy.

If you really need to use the system wxWidgets, then a way must be found to call Fuse functions using the old ABI from inside VeraCrypt that is build using the new ABI...not sure if this is possible. Ideas are welcomed.

Draky wrote Oct 29, 2015 at 3:15 PM

Ok.

I'm an Ubuntu 15.10 user.

Others above didn't say it but I use Veracrypt from the Unit193 PPA : https://launchpad.net/~unit193/+archive/ubuntu/test?field.series_filter=wily

I understand that there is a problem but... I will not try any compilation thing and so...
I'm not a dev/coder.

Maybe Unit193 will be able to solve this.

idrassi wrote Oct 29, 2015 at 3:45 PM

@Draky: thank for the clarification about the PPA use.

For the mean time, you can use the official VeraCrypt Linux installer which is availble also on Launchpad: https://launchpad.net/veracrypt/+download. For the latest version 1.16, the file to download is veracrypt-1.16-setup.tar.bz2: extract it and then launch veracrypt-1.16-setup-gui-x64 or veracrypt-1.16-setup-gui-x86.

Draky wrote Oct 29, 2015 at 4:00 PM

Yes, I confirm it works : I downloaded the install file from your website :)

I purged/removed the Veracrypt from Unit193, removed the PPA, uncompressed your setup files, ran it and now it works :)
And I still have a Unity dash icon ;)
Missing the systray though but not so important :)

idrassi wrote Mar 17, 2016 at 2:29 PM

I have pushed a commit that uses the -D_GLIBCXX_USE_CXX11_ABI=0 idea mentionned in my first comment and that solves the issue when linking against static wxWidgets that we build ourselves using WXTATIC=1: https://veracrypt.codeplex.com/SourceControl/changeset/60a35aa5c78d438e971d253cd42157c452928d29

Here is an extract of the relevant code in src\Makefile:
    GCC5USED := $(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 5)
    ifeq "$(GCC5USED)" "1"
        CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0
        WXCONFIG_CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0
    endif
So at this stage the issue exist only if VeraCrypt is linked against the system wxWidgets library on Linux distributions that use gcc-5 by default.

idrassi wrote Mar 18, 2016 at 4:44 PM

I was able to find the root caused of the issue: the new gcc-5 STL implementation has a problem that is causing char* pointers retrieved from std::string using c_str method to become invalid in the child of a child process (after two fork calls).
In our case, values are put in a std::list<string> variable which is passed to a first child (first fork) that extracts char* pointers from the std::list elements using c_str method and then a second fork call is performed before using these pointers:
  • In gcc 4.x, this works as expected.
  • in gcc 5.x, the pointers become invalid after the second fork.
This explains why fuse_main was failing when VeraCrypt is built using gcc 5.x since it was receiving invalid argv pointers.

The workaround that I found is to first copy the std:string values in the child before calling the second fork.

To me, it is clear that this a gcc 5.x issue. Maybe someone would come up with a simple program that could reproduce this problem and then submit it to gcc developers.

I have pushed a commit the implements this workaround: https://veracrypt.codeplex.com/SourceControl/changeset/f309749edc8e5f628ea3fe75741dd550ee05a312

I'll close this issue. Feel free to reopen in case of problems.

idrassi wrote Feb 10 at 8:05 AM

I have received an update about this issue from Kyle Marek who developed a fix for the same issue for CipherShed. It turns out that this was not a GCC5 issue after all but rather a bug in foreach loop inherited from TrueCrypt which appears only with GCC5.
Here is his analysis:
Stepping through TrueCrypt code in a debugger revealed that TrueCrypt's "foreach" implementation is prone to reconstructing std::string. The implications of this are that the C string copying that's done in the original loop copies the char pointers of the std::string copy, which becomes unreliable as soon as the loop iteration completes (what happens to the memory afterwards is unpredictable). What makes your fix work is that your manual std::string construction that's done within the loop copies the buffer of the std::string copy while it's still valid. Notice that your second loop is not a foreach-loop, but a nice for-loop. I think if you replaced it with yet another foreach loop, you would recreate the issue.

GCC5 wasn't broken, and GCC5 didn't break the TrueCrypt code. It's just always been broken and it was mere coincidence that the foreach loop worked "successfully".
.
Here is the commit Kyle made for CipherShed: https://github.com/CipherShed/CipherShed/commit/71ca808157731eb329496ef15e2282efa4aed9f8

It looks like we will have to check all occurrences of this foreach look in the code in order to detect potential issues.