vgough / encfs

EncFS: an Encrypted Filesystem for FUSE.
https://vgough.github.io/encfs/
Other
2.06k stars 278 forks source link

segmentation fault on Blowfish since ubuntu jammy #651

Open rgoede opened 2 years ago

rgoede commented 2 years ago

If I run jammy in docker and create an encfs filesystem with blowfish I get a segmentation fault (on my real machine the same segmentation fault prevents me from mounting a filesystem created in an earlier version). I run run --rm -it ubuntu:jammy bash and in the docker shell I run apt update && apt install -y encfs && encfs ~/.crypt ~/crypt. Then I answer y to directory creation, x for expert mode, 2 for blowfish and all default except for filename encoding which is 1. The system fails before asking for a password. Doing the same thing on impish works like a charm. Both say they use encfs 1.9.5.

The full output is:

~$ docker run --rm -it ubuntu:jammy bash
root@47d2ee14ec92:/# apt update && apt install -y encfs && encfs ~/.crypt  ~/crypt
Get:1 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [109 kB]             
Get:3 http://archive.ubuntu.com/ubuntu jammy-backports InRelease [90.7 kB]
Get:4 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Get:5 http://archive.ubuntu.com/ubuntu jammy/restricted amd64 Packages [164 kB]
Get:6 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages [1792 kB]
Get:7 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages [17.5 MB]
Get:8 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [85.3 kB]
Get:9 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 Packages [61.4 kB]
Get:10 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [61.3 kB]
Get:11 http://archive.ubuntu.com/ubuntu jammy/multiverse amd64 Packages [266 kB]             
Get:12 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [102 kB]
Get:13 http://archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [78.8 kB]
Get:14 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [174 kB]
Fetched 20.8 MB in 3s (6342 kB/s)                          
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
3 packages can be upgraded. Run 'apt list --upgradable' to see them.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  fuse libfuse2 libtinyxml2-9
The following NEW packages will be installed:
  encfs fuse libfuse2 libtinyxml2-9
0 upgraded, 4 newly installed, 0 to remove and 3 not upgraded.
Need to get 555 kB of archives.
After this operation, 2195 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy/universe amd64 libfuse2 amd64 2.9.9-5ubuntu3 [90.3 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy/universe amd64 libtinyxml2-9 amd64 9.0.0+dfsg-3 [32.5 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy/universe amd64 fuse amd64 2.9.9-5ubuntu3 [27.0 kB]
Get:4 http://archive.ubuntu.com/ubuntu jammy/universe amd64 encfs amd64 1.9.5-1build5 [405 kB]
Fetched 555 kB in 0s (2460 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package libfuse2:amd64.
(Reading database ... 4395 files and directories currently installed.)
Preparing to unpack .../libfuse2_2.9.9-5ubuntu3_amd64.deb ...
Unpacking libfuse2:amd64 (2.9.9-5ubuntu3) ...
Selecting previously unselected package libtinyxml2-9:amd64.
Preparing to unpack .../libtinyxml2-9_9.0.0+dfsg-3_amd64.deb ...
Unpacking libtinyxml2-9:amd64 (9.0.0+dfsg-3) ...
Selecting previously unselected package fuse.
Preparing to unpack .../fuse_2.9.9-5ubuntu3_amd64.deb ...
Unpacking fuse (2.9.9-5ubuntu3) ...
Selecting previously unselected package encfs.
Preparing to unpack .../encfs_1.9.5-1build5_amd64.deb ...
Unpacking encfs (1.9.5-1build5) ...
Setting up libfuse2:amd64 (2.9.9-5ubuntu3) ...
Setting up libtinyxml2-9:amd64 (9.0.0+dfsg-3) ...
Setting up fuse (2.9.9-5ubuntu3) ...
Setting up encfs (1.9.5-1build5) ...
debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 78.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.34.0 /usr/local/share/perl/5.34.0 /usr/lib/x86
_64-linux-gnu/perl5/5.34 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.34 /usr/share/perl/5.34 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm l
ine 7.)
debconf: falling back to frontend: Teletype
Configuring encfs
-----------------

Encfs security information

According to a security audit by Taylor Hornby (Defuse Security), the current implementation of Encfs is vulnerable or potentially vulnerable to multiple types of attacks. For example, an attacker with
read/write access to encrypted data might lower the decryption complexity for subsequently encrypted data without this being noticed by a legitimate user, or might use timing analysis to deduce information.

Until these issues are resolved, encfs should not be considered a safe home for sensitive data in scenarios where such attacks are possible.

Processing triggers for libc-bin (2.35-0ubuntu3) ...
The directory "/root/.crypt/" does not exist. Should it be created? (y,N) y
The directory "/root/crypt/" does not exist. Should it be created? (y,N) y
Creating new encrypted volume.
Please choose from one of the following options:
 enter "x" for expert configuration mode,
 enter "p" for pre-configured paranoia mode,
 anything else, or an empty line will select standard mode.
?> x

Manual configuration mode selected.
The following cipher algorithms are available:
1. AES : 16 byte block cipher
 -- Supports key lengths of 128 to 256 bits
 -- Supports block sizes of 64 to 4096 bytes
2. Blowfish : 8 byte block cipher
 -- Supports key lengths of 128 to 256 bits
 -- Supports block sizes of 64 to 4096 bytes
3. CAMELLIA : 16 byte block cipher
 -- Supports key lengths of 128 to 256 bits
 -- Supports block sizes of 64 to 4096 bytes

Enter the number corresponding to your choice: 2

Selected algorithm "Blowfish"

Please select a key size in bits.  The cipher you have chosen
supports sizes from 128 to 256 bits in increments of 32 bits.
For example: 
128, 160, 192, 224, 256
Selected key size: 

Using key size of 128 bits

Select a block size in bytes.  The cipher you have chosen
supports sizes from 64 to 4096 bytes in increments of 8.
Or just hit enter for the default (1024 bytes)

filesystem block size: 

Using filesystem block size of 1024 bytes

The following filename encoding algorithms are available:
1. Block : Block encoding, hides file name size somewhat
2. Block32 : Block encoding with base32 output for case-insensitive systems
3. Null : No encryption of filenames
4. Stream : Stream encoding, keeps filenames as short as possible

Enter the number corresponding to your choice: 1

Selected algorithm "Block""

Enable filename initialization vector chaining?
This makes filename encoding dependent on the complete path, 
rather then encoding each path element individually.
[y]/n: 

Enable per-file initialization vectors?
This adds about 8 bytes per file to the storage requirements.
It should not affect performance except possibly with applications
which rely on block-aligned file io for performance.
[y]/n: 

Enable filename to IV header chaining?
This makes file data encoding dependent on the complete file path.
If a file is renamed, it will not decode sucessfully unless it
was renamed by encfs with the proper key.
If this option is enabled, then hard links will not be supported
in the filesystem.
y/[n]: 

Enable block authentication code headers
on every block in a file?  This adds about 8 bytes per block
to the storage requirements for a file, and significantly affects
performance but it also means [almost] any modifications or errors
within a block will be caught and will cause a read error.
y/[n]: 

Add random bytes to each block header?
This adds a performance penalty, but ensures that blocks
have different authentication codes.  Note that you can
have the same benefits by enabling per-file initialization
vectors, which does not come with as great of performance
penalty. 
Select a number of bytes, from 0 (no random bytes) to 8: 

Enable file-hole pass-through?
This avoids writing encrypted blocks when file holes are created.
[y]/n: 

Configuration finished.  The filesystem to be created has
the following properties:
Filesystem cipher: "ssl/blowfish", version 3:0:2
Filename encoding: "nameio/block", version 4:0:2
Key Size: 128 bits
Block Size: 1024 bytes
Each file contains 8 byte header with unique IV data.
Filenames encoded using IV chaining mode.
File holes passed through to ciphertext.

Now you will need to enter a password for your filesystem.
You will need to remember this password, as there is absolutely
no recovery mechanism.  However, the password can be changed
later using encfsctl.

Segmentation fault (core dumped)
root@47d2ee14ec92:/# 
jade-lynx commented 2 years ago

Just want to add that I'm seeing the same behavior under Pop_OS! 22.04LTS (which is derived from Ubuntu). As with the other user, I'm also getting it with an old encfs filesystem, which I confirmed was using blowfish. Slight difference of behavior with the old filesystem compared to the example in the report, it does let you enter the password before crashing. Running verbose shows:

VERBOSE Root directory: /home/xxx/files/ [main.cpp:686] VERBOSE Fuse arguments: (daemon) (threaded) (keyCheck) encfs /home/xxx/crypt/ -o use_ino -o default_permissions [main.cpp:687] VERBOSE checking if ssl/aes(3:0:2) implements ssl/blowfish(2:1) [Interface.cpp:103] VERBOSE checking if ssl/blowfish(3:0:2) implements ssl/blowfish(2:1) [Interface.cpp:103] VERBOSE allocated cipher ssl/blowfish, keySize 20, ivlength 8 [SSL_Cipher.cpp:395] VERBOSE useStdin: 0 [FileUtils.cpp:1660] EncFS Password: VERBOSE checking if ssl/aes(3:0:2) implements ssl/blowfish(2:1) [Interface.cpp:103] VERBOSE checking if ssl/blowfish(3:0:2) implements ssl/blowfish(2:1) [Interface.cpp:103] VERBOSE allocated cipher ssl/blowfish, keySize 20, ivlength 8 [SSL_Cipher.cpp:395] Segmentation fault (core dumped)

(with some paths obfuscated above). Version is 1.9.5, again as above.

jade-lynx commented 2 years ago

After spending time in a debugger and digging through the OpenSSL docs, I figured out what was going on. The short form is that the Blowfish algorith is no longer a default OpenSSL algorithm, and has been moved to a 'legacy' provider; you can get things working again by enabling the legacy provider in your OpenSSL configuration, an example of this can be seen in section 6.2 of https://wiki.openssl.org/index.php/OpenSSL_3.0. On my machine, this involved editing /etc/ssl/openssl.cnf to include (modifies the existing [provider_sect] and [default_sect] sections):

[provider_sect]
default = default_sect
legacy = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1

Doing this enabled me to access my encrypted files again. Hurrah!

Some additional details: the SIGSEGV also occurs in the encfs unit test suite and 'checkops' test program, which helped a lot when debugging. It became clear that the crash happened on the call to openssl's EVP_CIPHER_CTX_set_key_length; building a debug version of openssl confirmed that it still happened in the current version, at the point where the provider is checked for the cipher. Digging in the docs to understand providers eventually showed me that Blowfish was not supplied by the default provider, but by the legacy provider, which needs explicit loading; and thankfully for a workaround, that can be done via config file.

Presumably as a user I need to look at moving my encfs directory to AES, assuming Blowfish is deprecated for a good reason.

From a coding perspective, presumably encfs should deprecate Blowfish; the openssl 'legacy' provider can be loaded through code as well as config, so I would assume that should be explicitly done in encfs, along with a warning to give some time for people to migrate away from it; and eventually removed completely from encfs. For whatever that's worth, of course!

rgoede commented 2 years ago

I can confirm that the workaround from @jade-lynx works and I have used it to migrate to gocryptfs because this project is dead.

bernhardu commented 1 year ago

This downstream Debian bug seems about the same issue.

And this crash seems also similar to one observed in freerdp. There a patch got disussed to programmatically load the openssl legacy provider, which might be a possible solution for encfs too.