signalapp / Signal-Desktop

A private messenger for Windows, macOS, and Linux.
https://signal.org/download
GNU Affero General Public License v3.0
14.43k stars 2.62k forks source link

Signal v1.15.0 and newer crash on startup on Fedora Linux 28/29 (and others), libcrypto related during DB operations (induced by sqlcipher binaries) #2634

Open mandree opened 6 years ago

mandree commented 6 years ago

Bug description

Signal crashes on startup with a SIGSEGV.

Steps to reproduce

  1. Build 1.15.2 from source on Fedora Linux 28,
  2. run it.

Actual result:

Gets killed with SIGSEGV. This is the console output:

{"name":"log","hostname":"redacted","pid":6583,"level":30,"msg":"app ready","time":"2018-08-07T23:07:39.573Z","v":0}
{"name":"log","hostname":"redacted","pid":6583,"level":30,"msg":"Ensure attachments directory exists","time":"2018-08-07T23:07:39.581Z","v":0}
{"name":"log","hostname":"redacted","pid":6583,"level":30,"msg":"updateSchema: Current schema version: 0; Most recent schema version: 1; SQLite version: 3.20.1; SQLCipher version: 3.4.2;","time":"2018-08-07T23:07:39.585Z","v":0}
{"name":"log","hostname":"redacted","pid":6583,"level":30,"msg":"updateToSchemaVersion1: starting...","time":"2018-08-07T23:07:39.586Z","v":0}

And then it crashes. This is the backtrace from GDB. If more details are needed, please let me know the magic of Signal's build rig to make it a build with debug symbols. I am a C programmer but unfamiliar with node, yarn, and thereabouts.

#0  0x00007fffe8f0db89 in EVP_MD_CTX_clear_flags () at /lib64/libcrypto.so.1.1
#1  0x00007fffe8efdd21 in EVP_DigestInit_ex () at /lib64/libcrypto.so.1.1
#2  0x00007fffe8f1bc3a in HMAC_Init_ex () at /lib64/libcrypto.so.1.1
#3  0x00007fffd544167a in sqlcipher_openssl_hmac () at /tmp/.org.chromium.Chromium.QBxD7N
#4  0x00007fffd545e245 in sqlcipher_page_cipher () at /tmp/.org.chromium.Chromium.QBxD7N
#5  0x00007fffd5479410 in sqlite3Codec () at /tmp/.org.chromium.Chromium.QBxD7N
#6  0x00007fffd549ac31 in pager_write_pagelist () at /tmp/.org.chromium.Chromium.QBxD7N
#7  0x00007fffd54aa3d0 in sqlite3PagerCommitPhaseOne.part.606 () at /tmp/.org.chromium.Chromium.QBxD7N
#8  0x00007fffd54aa5d1 in sqlite3BtreeCommitPhaseOne.part.607 () at /tmp/.org.chromium.Chromium.QBxD7N
#9  0x00007fffd54c850d in sqlite3VdbeHalt () at /tmp/.org.chromium.Chromium.QBxD7N
#10 0x00007fffd54e0132 in sqlite3VdbeExec () at /tmp/.org.chromium.Chromium.QBxD7N
#11 0x00007fffd54eb9c0 in sqlite3_step () at /tmp/.org.chromium.Chromium.QBxD7N
#12 0x00007fffd542fd11 in node_sqlite3::Statement::Work_Run(uv_work_s*) () at /tmp/.org.chromium.Chromium.QBxD7N
#13 0x00007ffff7cf2dbe in  () at /opt/Signal/libnode.so
#14 0x00007ffff68ed594 in start_thread () at /lib64/libpthread.so.0
#15 0x00007fffefd6e0df in clone () at /lib64/libc.so.6

Expected result:

Proper start up.

Screenshots

Platform info

Signal version:

v1.15.2 as Git tag.

Operating System:

Fedora Linux 28

Linked device version:

8.0.0

Link to debug log

can't obtain one. See above for what I've got.

scottnonnenberg-signal commented 6 years ago

In our @journeyapp/node-sqlcipher dependency, there is a linux build of openssl (libcrypto). Looks like it's the problem, based on that stacktrace. If you want to debug it, you can go to my fork of that dependency and see if you can get it working. Here are my most recent commits: https://github.com/scottnonnenberg-signal/node-sqlcipher/commits/

Thanks for jumping in on this!

mandree commented 6 years ago

With the default Signal v1.15.3 from Git (without any node-sqlcipher upgrades), I get this - the ctx=0x0 looks suspicious to me, since the manual page states: "EVP_DigestInit_ex() sets up digest context ctx to use a digest type from ENGINE impl. ctx must be initialized before calling this function. type will typically be supplied by a function such as EVP_sha1(). If impl is NULL then the default implementation of digest type is used."

I still can't make head or tails of this since I don't know how/where/why these are called.

#0  0x00007fffe8f0db89 in EVP_MD_CTX_clear_flags (ctx=ctx@entry=0x0, flags=flags@entry=2) at crypto/evp/evp_lib.c:479
#1  0x00007fffe8efdd21 in EVP_DigestInit_ex (ctx=0x0, type=0x7fffe9225cc0 <sha1_md>, impl=0x0) at crypto/evp/digest.c:66
#2  0x00007fffe8f1bc3a in HMAC_Init_ex (ctx=0x28eac331a360, key=<optimized out>, len=<optimized 
out>, md=<optimized out>, impl=0x0) at crypto/hmac/hmac.c:70
...
richardschuetz commented 6 years ago

As can be seen from the stacktrace, the system's OpenSSL 1.1.0 library is used instead of the statically linked one. This can happen if the library is already loaded into the Electron process and its symbols take precedence. The crash is likely a result of SQLCipher expecting the older version of OpenSSL it was built against.

@scottnonnenberg-signal You can prevent this by compiling your version of libcrypto.a with hidden symbol visibility (e.g. ./Configure linux-x86_64 no-shared -fPIC -fvisibility=hidden). Including precompiled code from unknown sources in a so-called private messenger is highly debatable, though.

mandree commented 6 years ago

@scottnonnenberg-signal I think the approach of packing a static OpenSSL on Linux is not working for me although I understand it is trying to be helpful.

Basically we should not be mixing SSL stuff in the same program, and up to the lastest v1.14.x things went smoothly for me.

I am not sure if @richardschuetz 's proposal is right, the only way I have found through experimenting for hours on end is this script (snippet):

yarn add --force electron@2.0.7 @journeyapps/sqlcipher
yarn add electron-rebuild --dev
yarn generate
node_modules/.bin/electron-rebuild -f -w @journeyapps/sqlcipher
NODE_ENV=production NODE_APP_INSTANCE=production yarn run start

I can not package this build through yarn build-release --linux rpm though, which will rebuild sqlcipher in a different manner and then fail at run-time, not with SIGSEGV, but through not finding libcrypto.so.1.0.0. It appears it picks up a binary from journeyapps in this case, since that tries to bind against libcrypto.so.1.0.0. - I don't have that decrepit version on my system (Fedora 28).

I cannot yet your sqlcipher fork to work at all, the original one requires the rebuild-from-source as shown above.

scottnonnenberg-signal commented 6 years ago

@mandree That's not the right version of @journeyapps/sqlcipher - Signal Desktop uses a forked version of it because the version you've installed downloads a precompiled binary which is indeed linked against a very old version of libcrypto.

stemid commented 6 years ago

@richardschuetz where do you run this Configure line you mention? I use a spec file to build an RPM of signal-desktop for myself on Fedora 27 and I can't see where I'd insert this Configure line.

The %build part looks like this in my spec file.

%build
cd Signal-Desktop-%{version}
sed -i -- "s/    \"node\": .*/    \"node\": \"$(node -v | cut -b 2-)\"/g" package.json
PATH=node_modules/.bin:$PATH yarn install

yarn install --frozen-lockfile
yarn generate --force
yarn prepare-beta-build
yarn build-release --linux dir

I also get segfault but even in the latest 1.15.3 version. I tried going back to 1.15.1 and still get segfault. Also tried removing my .config/Signal dir but that didn't help. The last version I can successfully build and run with my RPM spec file is 1.14.4. They all build but only 1.14.4 runs without segfault.

mandree commented 6 years ago

@scottnonnenberg-signal what I am trying to do is build Fedora 28 packages of Signal for several computers I oversee and deploy it.

A statically linked obsolete OpenSSL version from Ubuntu 14.04 appears not to work on Fedora 28 (or Arch for that matter) for various reasons: they do not blend in with a different distribution that uses different policies, versions, paths, and possibly other reasons.

So IMO what I/we need to do is rebuild sqlcipher all from source, link dynamically against the system's OpenSSL library (as the original journeyapps/sqlcipher claims to do) and forbid it to use any precompiled binaries. The electron-rebuild run on the original sqlcipher exacts just that for the "yarn run start", but if I run yarn build-release, it clobbers the results of the electron-rebuild, rebuilds sqlcipher again (pulling in the binary) and then boom.

Bottom line, I want to recompile sqlcipher and waive any binaries
- how do I do that? Fork sqlcipher again and remove all binaries? Or is there an easier way through signal's configuration?

mandree commented 6 years ago

Success. Following up my own post, after researching, reading, experimenting, learning, I have achieved my goal.

I have ended up using the original @journeyapps/sqlcipher, hack its "install" configuration in package.json to --build-from-source, install the hacked module as requisite.

My build script for Fedora 28 currently used as shown below, works with v1.15.4 and generates a functioning app that is dynamically linked against libcrypto.so.1.1. I understand that may not be good for distribution, but the same approach should satisfy anything that builds from source and goes shipwrecked by the statically linked Ubuntu 14.04 OpenSSL crap.

WARNING this is not for developers who hack on Signal due to the brutal git reset --hard/git clean below, it will clobber any and all of your changes! It is to do a clean rebuild from a Git release tag.

#!/bin/sh
# Shell script to rebuild Signal from scratch.
# Assumes that the Git tree is checked out on a release tag,
# as it talks to the production servers.
#
# Tested on Fedora 28 with Signal v1.15.4 from Git.
#
# Requires yarn, and jq <https://stedolan.github.io/jq/>.
#
# © 2018 Matthias Andree. GNU GPL v2 or later.

### ADJUST THIS TO WHERE THE CHECKOUT IS ###
DIR="$HOME/VCS-other/signal-desktop.git"

### NO USER SERVICEABLE PARTS BELOW ###
set -ex
cd "$DIR"

# revert to a clean Git checkout
git reset --hard
git clean -fdxq -e release

# update electron, security fix time
yarn add --dev electron@~2.0.3  # electron-rebuild 

# patch @journeyapps/sqlcipher to nuke binaries
# try and use a local copy of sqlcipher based on the original one
yarn add --force @journeyapps/sqlcipher
d=.tmp-ja-sqlc
rm -rf "$d"
mkdir "$d"
cp -pR node_modules/@journeyapps/sqlcipher "$d"
jq \
    'del(.bundledDependencies)|. * {"scripts":{"install":"node-pre-gyp install --build-from-source"}}' \
    $d/sqlcipher/package.json  >.$$ \
    && mv .$$ $d/sqlcipher/package.json
# purge cache just in case (we didn't change version)
rm -rf $(yarn cache dir)/npm-@journeyapps/sqlcipher-*
yarn add --force file://$(realpath $d/sqlcipher)

# build
yarn generate

yarn --verbose build-release --linux rpm
ls -lbdtr release/*.rpm

# now run the thing:
NODE_ENV=production NODE_APP_INSTANCE=production yarn run start & disown $!

(side RANT: Note that Ubuntu "long-term-support" is a red herring, it only applies to a few dozen base packages that are core to ubuntu server, on the Desktop it's useless as most packages go out of support after a few months, and we should not encourage users to use privacy/security-sensitive stuff on top of a rocking and sliding pile of unmaintained packages. Don't build on Ubuntu 14.04. It enhances compatibility but only permits users to stay on their outdated/insecure installs longer.)

duckinator commented 6 years ago

Reproduced with Signal v1.15.5 on Fedora 28, building from the zip file linked to on https://github.com/signalapp/Signal-Desktop/releases/tag/v1.15.5 .

Vaelatern commented 5 years ago

Reproduced on a LibreSSL-based Void Linux system. If it at least had a binary, then our checks would direct any looking for libcrypto.so to the correct lib, but this seems to be done (hopefully accidentally) to require a very specific library name and version.

Vaelatern commented 5 years ago

It should be noted that "So the Signal-Desktop build uses a fork of this project," instead of the upstream for node-sqlcipher. https://github.com/journeyapps/node-sqlcipher/issues/8

d-hansen commented 5 years ago

FWIW: the above steps of patching @journeyapps/sqlcipher (and performed in principal) worked for 'git checkout tags/v1.17.2'.

fholzer commented 5 years ago

Unfortunately @mandree's shell script no longer works because the node-sqlcipher fork Signal is using added support for FTS5, which isn't present in the original. I created journeyapps/node-sqlcipher#17 to get it added to the original package.

mandree commented 5 years ago

I found https://copr.fedorainfracloud.org/coprs/luminoso/Signal-Desktop/ (and rebuilt the RPMs on F29 from commit 6cd8e8411), which seems to work on F29. The .spec file can be browsed at https://copr-dist-git.fedorainfracloud.org/cgit/luminoso/Signal-Desktop/signal-desktop.git/tree/signal-desktop-arch.spec?h=f29&id=6cd8e8411c58c19cf9154da0eafa64fb1f5450ff and it appears to work for me. So I wonder if there's an easier approach than fixing my build script... it would be good though if Signal could be built OOTB without any further patching.

fholzer commented 5 years ago

Once journeyapps/node-sqlcipher#17 is merged the Signal maintainers could switch back to from the fork they're currently using. The fork links statically against libcrypto which is causing issues with a number of distributions.

Edit: typo

mandree commented 5 years ago

@fholzer https://github.com/journeyapps/node-sqlcipher/commit/2998fbe5f205c1999cdef068376c6c8634e5605a

fholzer commented 5 years ago

Yeah, i noticed. We'll need to wait for a new version to be published to npm...

Edit: Actually no, the dependency is pointing to some github repo at the moment anyway, so I guess that's OK. So Signal just needs to update their package.json.

Edit2: Nevermind.

:+1:

(FYI i had to clear my ~/.cache/Signal directory to make it work)

stemid commented 5 years ago

@fholzer which version did you try that with? I did it with v1.23.1 but it crashed at startup.

$ NODE_ENV=production NODE_APP_INSTANCE=production yarn run start & disown $!                                                                                                                   
[1] 11123                                                                                                                                                                                                                             
yarn run v1.15.2
$ electron .
Set Windows Application User Model ID (AUMID) { appUserModelId: 'org.whispersystems.signal-desktop' }
NODE_ENV production
NODE_CONFIG_DIR /home/stemid/src/Signal-Desktop/config
NODE_CONFIG {}
ALLOW_CONFIG_MUTATIONS undefined
HOSTNAME undefined
NODE_APP_INSTANCE undefined
SUPPRESS_NO_CONFIG_WARNING undefined
userData: /home/stemid/.dotfiles/.config/Signal
config/get: Did not find user config file, cache is now empty object
config/get: Did not find ephemeral config file, cache is now empty object
making app single instance
App threw an error during load
TypeError: app.requestSingleInstanceLock is not a function
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/main.js:101:23)
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/main.js:990:3)
    at Module._compile (module.js:642:30)
    at Object.Module._extensions..js (module.js:653:10)
    at Module.load (module.js:561:32)
    at tryModuleLoad (module.js:504:12)
    at Function.Module._load (module.js:496:3)
    at loadApplicationPackage (/home/stemid/src/Signal-Desktop/node_modules/electron/dist/resources/default_app.asar/main.js:287:12)
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/node_modules/electron/dist/resources/default_app.asar/main.js:328:5)
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/node_modules/electron/dist/resources/default_app.asar/main.js:365:3)
Unhandled Error: TypeError: app.requestSingleInstanceLock is not a function
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/main.js:101:23)
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/main.js:990:3)
    at Module._compile (module.js:642:30)
    at Object.Module._extensions..js (module.js:653:10)
    at Module.load (module.js:561:32)
    at tryModuleLoad (module.js:504:12)
    at Function.Module._load (module.js:496:3)
    at loadApplicationPackage (/home/stemid/src/Signal-Desktop/node_modules/electron/dist/resources/default_app.asar/main.js:287:12)
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/node_modules/electron/dist/resources/default_app.asar/main.js:328:5)
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/node_modules/electron/dist/resources/default_app.asar/main.js:365:3)
Unhandled Error
TypeError: app.requestSingleInstanceLock is not a function                                                                                                                                                                             
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/main.js:101:23)                                                                                                                                                             
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/main.js:990:3)                                                                                                                                                              
    at Module._compile (module.js:642:30)                                                                                                                                                                                              
    at Object.Module._extensions..js (module.js:653:10)                                                                                                                                                                                
    at Module.load (module.js:561:32)                                                                                                                                                                                                  
    at tryModuleLoad (module.js:504:12)                                                                                                                                                                                                
    at Function.Module._load (module.js:496:3)                                                                                                                                                                                         
    at loadApplicationPackage (/home/stemid/src/Signal-Desktop/node_modules/electron/dist/resources/default_app.asar/main.js:287:12)                                                                                                   
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/node_modules/electron/dist/resources/default_app.asar/main.js:328:5)                                                                                                        
    at Object.<anonymous> (/home/stemid/src/Signal-Desktop/node_modules/electron/dist/resources/default_app.asar/main.js:365:3)                                                                                                        
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
mandree commented 5 years ago

Arch Linux are using a patch to link libcrypto dynamically rather than statically - this appears to fix crashes for me on Fedora 29, too. Link: https://aur.archlinux.org/cgit/aur.git/tree/openssl-linking.patch?h=signal

fholzer commented 5 years ago

@stemid I'm on 1.22.0 at the moment. Had some issues with 1.23.x myself, but no time to look into it in more detail yet.

@mandree not sure which sqlcipher package Arch uses, but the file that seems to get patched with the file you linked is actually linking dynamically already: https://github.com/journeyapps/node-sqlcipher/blob/master/deps/sqlite3.gyp#L75 Maybe I missed something?

mandree commented 5 years ago

@mandree not sure which sqlcipher package Arch uses, but the file that seems to get patched with the file you linked is actually linking dynamically already: https://github.com/journeyapps/node-sqlcipher/blob/master/deps/sqlite3.gyp#L75 Maybe I missed something?

@fholzer as of v1.23.1, sqlcipher isn't pulled from in its master branch, but from a frozen version of Scott Nonnenberg's clone:

$ grep node-sqlcipher * 2>/dev/null
package.json:    "@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#2e28733b61640556b0272a3bfc78b0357daf71e6",
yarn.lock:"@journeyapps/sqlcipher@https://github.com/scottnonnenberg-signal/node-sqlcipher.git#2e28733b61640556b0272a3bfc78b0357daf71e6":
yarn.lock:  resolved "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#2e28733b61640556b0272a3bfc78b0357daf71e6"
fholzer commented 5 years ago

Right.

So Signal just needs to update their package.json.

What I meant was that they can switch to journeyapps' version, now that it supports FTS5. Then the whole libcrypto issue would be resolved for everyone, right?

fholzer commented 5 years ago

@stemid I was able to resolve my build issues with v1.23.2.

Here's what worked for me:

# "fix" package.json engine, sqlcipher dependency, build target as described in my previous comment
# below rm commands remove data from previous build and dependencies of previously checked out older version of signal
rm -rf node_modules/
rm -rf release/
rm -rf .tmp*
yarn install
yarn grunt
yarn icon-gen
yarn build-release
# install .rpm or .deb from release directory

see https://github.com/signalapp/Signal-Desktop/blob/development/CONTRIBUTING.md#all-platforms

Let me know if this helps

stemid commented 5 years ago

@fholzer thanks for that but it failed during yarn install. Tried it with a new git repo, your mods.

Output: https://bpaste.net/show/9fc922f28d05

Fedora 28 with node and node-gyp installed from packages. Maybe I need later versions of those?

fholzer commented 5 years ago

@stemid not entirely sure what to make of this... have you had a look at https://github.com/nodejs/node-gyp/issues/809? there's one comment in particular that seemed to have help a lot of ppl, maybe give that a try? https://github.com/nodejs/node-gyp/issues/809#issuecomment-155019383

In case that doesn't help, can you run make BUILDTYPE=Release -C build in ./node_modules/@journeyapps/sqlcipher/? I'm curious about the output.

Fedora 28 with node and node-gyp installed from packages. Maybe I need later versions of those?

That's a possibility, though I'm no expert in regards to compiling native node modules. Some ppl suggested outdated vars in ~/.npmrc in the thread I linked. Not sure... sorry Here's what I'm running:

Signal-Desktop$ node -v
v10.15.0
Signal-Desktop$ npm -v
6.9.0
Signal-Desktop$ yarn -v
1.9.4
Signal-Desktop$ npx node-gyp -v # this should be installed by Signal
v3.8.0

Have you ever successfully built Signal with your setup? (sqlcipher in particular)

ckujau commented 5 years ago

The patch from comment 478328776 worked for me, but applying could only be done after the first yarn install, and then my nodejs binary from Fedora 29 was too new, so stringing all this together, here is how I got Signal-Desktop running again:

wget "https://aur.archlinux.org/cgit/aur.git/plain/openssl-linking.patch?h=signal" -O ~/openssl-linking.patch
sed -i.bak "s/node\": \"10.13.0/node\": \"$(node --version | sed 's/v//')/" package.json

yarn install --frozen-lockfile
patch -p1 < ~/openssl-linking.patch 
sudo chattr +i node_modules/@journeyapps/sqlcipher/deps/sqlite3.gyp      # Err...

yarn generate
SIGNAL_ENV=production yarn build-release
NODE_ENV=production NODE_APP_INSTANCE=production yarn run start --disable-gpu

Still, this bug is open for way too long and I don't understand why Signal desktop should only be a thing for MacOS or Windows users, especially considering most tinfoil hats (hello, myself!) would run Linux anyway. This report even includes fixes, can't they just be applied to upstream to finally resolve this one?

stemid commented 5 years ago

@ckujau This method worked for me on F28 with v1.24.1! Thank you so much. I haven't seen Signal-desktop running for almost a year now, iirc.

I only skipped the chattr line.

brian-provenzano commented 5 years ago

Still, this bug is open for way too long and I don't understand why Signal desktop should only be a thing for MacOS or Windows users, especially considering most tinfoil hats (hello, myself!) would run Linux anyway. This report even includes fixes, can't they just be applied to upstream to finally resolve this one?

I agree this is why I just gave up on Signal... I can't see why they cannot take this info (or info in multiple threads in regards to RPMs/Fedora functionality) and create a build.

mandree commented 5 years ago

I agree this is why I just gave up on Signal... I can't see why they cannot take this info (or info in multiple threads in regards to RPMs/Fedora functionality) and create a build.

I haven't tested these builds, but it appears there's a COPR:

brian-provenzano commented 5 years ago

I haven't tested these builds, but it appears there's a COPR:

Yeah I've seen these. Thing is if I am using a security application I want it built and provided by the company producing it.

hsanjuan commented 4 years ago

The snap-packaged application is also broken because of this, along with openSUSE Tumbleweed. Maybe when Signal sigfaults in absolutely every Linux distro something will be done about it?

buscher commented 4 years ago

Hello!

I have a crashing Signal too, my backtrace looks similar to the initial posted. Lets me try to sum up my investigations and please correct me once you spot the error.

This is the scenario on my laptop. Gentoo btw. On my desktop (also Gentoo), it works fine, because I do not have any disc encryption. libmount.so.1 does not depend on libcryptsetup.so.12 in this case, no cryptsetup compiled in.

Conclusion: Signal can not be used Linux installations with (encrypted fs and) cryptsetup with OpenSSL backend?

OR

Hypothesis: Signal can be used on Linux installations with cryptsetup with OpenSSL backend IF they match the OpenSSL version used in the Signal version? Question: which OpenSSL version is used in Signal?

or is there any other workaround which I missed? :) or am I totally wrong here and did not understand the ticket at all?

hsanjuan commented 4 years ago

@buscher workaround is patching one of the dependencies (see above https://github.com/signalapp/Signal-Desktop/issues/2634#issuecomment-485041199)

bprfh commented 4 years ago

@buscher as hsanjuan said, you have to either patch a dependency, or replace the dependency If you want, you can use this script to replace the dependency and build it automatically: #!/bin/bash source ~/.bashrc rm -rf "./Signal-Desktop" git clone https://github.com/signalapp/Signal-Desktop.git cd Signal-Desktop sed 's/"@journeyapps\/sqlcipher.*/"@journeyapps\/sqlcipher": "4.0.0",/g' package.json package.json.tmp && mv package.json.tmp package.json nvm use if hash nvm 2>/dev/null; then nvm use else echo "Warning, no NVM found, you need to have the exact node version installed" fi yarn install yarn grunt
yarn icon-gen
yarn build-release

After that you can start the binary from the signal/release/linux-unpacked directory

mandree commented 4 years ago

@scottnonnenberg-signal can this issue please be addressed in the next release? It's been open for one and a half years and the cause is known.

To all other users: please refrain from posting "me too" with just changed minor details of solutions, the cause and its workaround are sufficiently documented already. If in doubt whether your information is already contained here, the slightest doubt => do not post comments here.

scottnonnenberg-signal commented 4 years ago

@mandree We don't officially support any Linux platform other than Debian-based Linux distributions, via our official apt packages. We welcome assistance in making Signal Desktop more accessible to other distributions, but right now we can't spend much time on it. And we won't be changing our SQLCipher/OpenSSL build approach, statically linking everything.

So the best way to help us is to research then provide low-impact changes we could apply to our existing setup.

bprfh commented 4 years ago

@scottnonnenberg-signal Sorry to jump in like this, but I think there is misconumication

Currently you can't run signal on any linux distribution except ubuntu. This is because your forked version of sqlcipher links against a static openssl library.

The solution would be to either change your forked sqlcipher repository to not link against a static openssl, or use the upstream one. I can gladly do a pull request for that but I don't know why you forked the sqlcipher repository and don't use the upstream one, so I don't think that would be the solution.

To be clear: If you replace the line 65 in package.json: "@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#b10f232fac62ba7f8775c9e086bb5558fe7d948b", With: "@journeyapps/sqlcipher": "4.0.0", Signal builds and runs fine on Fedora, in fact I run it this way.

scottnonnenberg-signal commented 4 years ago

Currently you can't run signal on any linux distribution except ubuntu. This is because your forked version of sqlcipher links against a static openssl library.

This is not correct. I've tested Signal Desktop successfully not just on Ubuntu, but also Debian. And Linux Mint, and Kubuntu, a step or two away from Ubuntu itself. Perhaps you haven't tried with the most recent builds?

bprfh commented 4 years ago

My apologizes, did you change anything regarding sqlcipher? The build succeeds from source right now for me. Last failed rebuild should be either around 23.02.2020 or a signal version earlier on fedora 31

Could somebody else comment if it stills fails for them?

lnicola commented 4 years ago

Arch patches the openssl dependency: https://git.archlinux.org/svntogit/community.git/tree/trunk/openssl-linking.patch?h=packages/signal-desktop.

d-hansen commented 4 years ago

My apologizes, did you change anything regarding sqlcipher? The build succeeds from source right now for me. Last failed rebuild should be either around 23.02.2020 or a signal version earlier on fedora 31

Could somebody else comment if it stills fails for them?

My guess would be that it builds (for now) due to this commit (updating the forked version of node-sqlcipher to 4.3.0 and updates the "packaged" openssl library to 1.1.1d: https://github.com/scottnonnenberg-signal/node-sqlcipher/commit/b10f232fac62ba7f8775c9e086bb5558fe7d948b

hsanjuan commented 4 years ago

My guess would be that it builds (for now)

This was not a build problem. It always built. The problem is the application died on start. I checked and it seems to run fine now that openssl was updated to 1.1.1d (openSUSE Tumbleweed).

I don't know why you forked the sqlcipher repository and don't use the upstream one

It seems the upstream does not include a statically-linked openssl for linux and is more outdated. Now, are those compiled by hand on a dev machine? If so, it seems there is a small dilemma here between using manually compiled binaries by a project dev vs. using the distribution's provided libraries.

mandree commented 4 years ago

Quoting @d-hansen:

My guess would be that it builds (for now) due to this commit (updating the forked version of node-sqlcipher to 4.3.0 and updates the "packaged" openssl library to 1.1.1d: scottnonnenberg-signal/node-sqlcipher@b10f232

For me, 68ee557dc apparently fixes the issue on Fedora 31 (i. e. v1.32.0-beta.2 and younger), yet I'd like to stress @d-hansen's "for now".

My concern is that the error will come back as OpenSSL is updated again in the distros over time on Linux. It would seem that working now is just a coincidence because .../node_modules/@journeyapps/sqlcipher/build/Release/obj/gen/sqlcipher-amalgamation-3030001/OpenSSL-Linux/libcrypto.a is 1.1.1d which happens to match the system-installed openssl-1.1.1d-2.fc31.x86_64.

Given that electron at least on Linux links to libcrypto.so dynamically (see below), it seems important that we prevent ever mixing a different version in, so I ask @scottnonnenberg-signal to please consider linking libcrypto dynamically for sqlcipher:

Downstream packagers have been patching node_modules/@journeyapps/sqlcipher/deps/sqlite3.gyp to replace Linux's '<(SHARED_INTERMEDIATE_DIR)/sqlcipher-amalgamation-<@(sqlite_version)/OpenSSL-Linux/libcrypto.a' by -lcrypto and possibly also ditching the openssl-include dir from the sqlcipher-amalgamation, and that appears to have worked.

This is on Fedora 31 amd64:

$ ldd node_modules/electron/dist/electron | grep crypto
    libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f24b4d00000)
    libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007f24b4a07000)
d-hansen commented 4 years ago

It is very nonsensical to me to have a product that touts security (of your messages) but then does not follow or track the latest updates to highly-vulnerable cryptography libraries. One would think that a product like signal would want to stay as current as possible and track the most recent versions and updates to OpenSSL and libcrypto specifically! Using a version of node/sqlcipher from 2 years ago (with fairly minimal updates) and then statically linking against libcrypto from a particular version of OpenSSL just seems so wrong in the security world. We want systems to quickly respond to CVE's. So, it likely won't be very long until the next rev of OpenSSL is released and of course, systems like Fedora, Ubuntu, etc are going to quickly upgrade to it. :(

lnicola commented 4 years ago

Not only that, but the encryption key is stored next to the database, while the attachments are unencrypted. I don't understand what scenario the encryption mitigates.

mandree commented 4 years ago

@scottnonnenberg-signal

@mandree We don't officially support any Linux platform other than Debian-based Linux distributions, via our official apt packages. We welcome assistance in making Signal Desktop more accessible to other distributions, but right now we can't spend much time on it. And we won't be changing our SQLCipher/OpenSSL build approach, statically linking everything.

So the best way to help us is to research then provide low-impact changes we could apply to our existing setup.

Scott, I understand time constraints, but I do not understand what the technical merit of "linking statically" is if it breaks portability. But then we need to do two things:

  1. Linking statically, you as maintainers must update to each and every security release of OpenSSL affecting libcrypto and re-release Signal. This is all but low-profile. Given the past interval of how rarely sqlcipher's reference in signal-desktop has changed, I'd say that linking libcrypto.a should be discontinued because that effort has not been sustained (see @d-hansen's comment above)
  2. For other distros, we would have to identify which packages have been built with different options on non-Ubuntu-LTS-distros and might pull in libcrypto.so, as happens on Fedora, and then modify or replace these. This is also everything, but not low-profile.

The proper course of action would seem to declare Ubuntu 16 unsupported and require a dynamic libcrypto.so.1.1 for now and build against 1.1 headers.

What currently happens is that some part of the build on Fedora (included module) pulls in libcrypto.so (as seen by my ldd screenshot) dynamically, and your sqlcipher pulls in libcrypto.a from a different source statically. This can cause symbols to be mixed from different library sources by linkers, and is technically unsound, is likely what caused the wreck on Fedora 28+ before 1.32. And that is why downstream packagers are switching to dynamic linking of libcrypto.

The given low-profile change is this: https://copr-dist-git.fedorainfracloud.org/cgit/luminoso/Signal-Desktop/signal-desktop.git/tree/signal.spec?id=5eab5275fab96abc9c55644cc2d1eb0f041fc38c#n64