Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building fails on OpenBSD due to missing sendmmsg in libc #5552

Open
h3artbl33d opened this issue May 11, 2024 · 11 comments
Open

Building fails on OpenBSD due to missing sendmmsg in libc #5552

h3artbl33d opened this issue May 11, 2024 · 11 comments
Labels
bug Something is not working

Comments

@h3artbl33d
Copy link

Description

In an effort to make Chatmail compatible with OpenBSD and OpenSMTPD, I ran into the issue where deltachat-core-rust won't install from source, due to an issue with quinn. Resolving it seems less trivial as noted in the respective repository.

Is there a feasible way to work around this issue? Eg, is quinn a hard dependency for deltachat-core-rust?

Details

  • Operating System: OpenBSD (OpenBSD 7.5-current (GENERIC.MP) #58: Thu May 9 13:42:15 MDT 2024)
  • Expected behavior: The crate installs as expected
  • Actual behavior: Fails due to a subdependency issue
  • Steps to reproduce the problem: Execute cargo install --git https://github.com/deltachat/deltachat-core-rust/ deltachat-rpc-server on OpenBSD
  • Logs:
$ cargo install --git https://github.com/deltachat/deltachat-core-rust/ deltachat-rpc-server

    Updating git repository `https://github.com/deltachat/deltachat-core-rust/`
    [...]
    Compiling quinn-udp v0.4.1
error[E0425]: cannot find value `IP_RECVTOS` in crate `libc`
    --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:99:75
     |
99   |         if let Err(err) = set_socket_option(&*io, libc::IPPROTO_IP, libc::IP_RECVTOS, OPTION_ON) {
     |                                                                           ^^^^^^^^^^ help: a constant with a similar name exists: `IP_RECVIF`
     |
    ::: /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.154/src/unix/bsd/netbsdlike/openbsd/mod.rs:1246:1
     |
1246 | pub const IP_RECVIF: ::c_int = 30;
     | ---------------------------- similarly named constant `IP_RECVIF` defined here

error[E0425]: cannot find value `IPV6_DONTFRAG` in crate `libc`
   --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:151:59
    |
151 |         set_socket_option(&*io, libc::IPPROTO_IPV6, libc::IPV6_DONTFRAG, OPTION_ON)?;
    |                                                           ^^^^^^^^^^^^^ not found in `libc`

error[E0412]: cannot find type `mmsghdr` in crate `libc`
   --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:177:26
    |
177 |       let mut msgs: [libc::mmsghdr; BATCH_SIZE] = unsafe { mem::zeroed() };
    |                            ^^^^^^^ help: a struct with a similar name exists: `cmsghdr`
    |
   ::: /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.154/src/unix/bsd/mod.rs:10:1
    |
10  | / s! {
11  | |     pub struct sockaddr {
12  | |         pub sa_len: u8,
13  | |         pub sa_family: sa_family_t,
...   |
125 | |     }
126 | | }
    | |_- similarly named struct `cmsghdr` defined here

error[E0412]: cannot find type `mmsghdr` in crate `libc`
   --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:321:24
    |
321 |       msgvec: *mut libc::mmsghdr,
    |                          ^^^^^^^ help: a struct with a similar name exists: `cmsghdr`
    |
   ::: /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.154/src/unix/bsd/mod.rs:10:1
    |
10  | / s! {
11  | |     pub struct sockaddr {
12  | |         pub sa_len: u8,
13  | |         pub sa_family: sa_family_t,
...   |
125 | |     }
126 | | }
    | |_- similarly named struct `cmsghdr` defined here

error[E0425]: cannot find value `SYS_sendmmsg` in crate `libc`
   --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:328:39
    |
328 |         let ret = libc::syscall(libc::SYS_sendmmsg, sockfd, msgvec, vlen, flags) as libc::c_int;
    |                                       ^^^^^^^^^^^^ not found in `libc`

error[E0412]: cannot find type `mmsghdr` in crate `libc`
   --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:360:24
    |
360 |       msgvec: *mut libc::mmsghdr,
    |                          ^^^^^^^ help: a struct with a similar name exists: `cmsghdr`
    |
   ::: /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.154/src/unix/bsd/mod.rs:10:1
    |
10  | / s! {
11  | |     pub struct sockaddr {
12  | |         pub sa_len: u8,
13  | |         pub sa_family: sa_family_t,
...   |
125 | |     }
126 | | }
    | |_- similarly named struct `cmsghdr` defined here

error[E0412]: cannot find type `mmsghdr` in crate `libc`
   --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:383:50
    |
383 |       let mut hdrs = unsafe { mem::zeroed::<[libc::mmsghdr; BATCH_SIZE]>() };
    |                                                    ^^^^^^^ help: a struct with a similar name exists: `cmsghdr`
    |
   ::: /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.154/src/unix/bsd/mod.rs:10:1
    |
10  | / s! {
11  | |     pub struct sockaddr {
12  | |         pub sa_len: u8,
13  | |         pub sa_family: sa_family_t,
...   |
125 | |     }
126 | | }
    | |_- similarly named struct `cmsghdr` defined here

error[E0412]: cannot find type `mmsghdr` in crate `libc`
   --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:448:24
    |
448 |       msgvec: *mut libc::mmsghdr,
    |                          ^^^^^^^ help: a struct with a similar name exists: `cmsghdr`
    |
   ::: /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.154/src/unix/bsd/mod.rs:10:1
    |
10  | / s! {
11  | |     pub struct sockaddr {
12  | |         pub sa_len: u8,
13  | |         pub sa_family: sa_family_t,
...   |
125 | |     }
126 | | }
    | |_- similarly named struct `cmsghdr` defined here

error[E0425]: cannot find value `SYS_recvmmsg` in crate `libc`
   --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:457:33
    |
457 |             libc::syscall(libc::SYS_recvmmsg, sockfd, msgvec, vlen, flags, timeout) as libc::c_int;
    |                                 ^^^^^^^^^^^^ not found in `libc`

error[E0412]: cannot find type `mmsghdr` in crate `libc`
   --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:489:24
    |
489 |       msgvec: *mut libc::mmsghdr,
    |                          ^^^^^^^ help: a struct with a similar name exists: `cmsghdr`
    |
   ::: /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.154/src/unix/bsd/mod.rs:10:1
    |
10  | / s! {
11  | |     pub struct sockaddr {
12  | |         pub sa_len: u8,
13  | |         pub sa_family: sa_family_t,
...   |
125 | |     }
126 | | }
    | |_- similarly named struct `cmsghdr` defined here

error[E0531]: cannot find unit struct, unit variant or constant `IP_RECVTOS` in crate `libc`
    --> /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/quinn-udp-0.4.1/src/unix.rs:629:73
     |
629  |             (libc::IPPROTO_IP, libc::IP_TOS) | (libc::IPPROTO_IP, libc::IP_RECVTOS) => unsafe {
     |                                                                         ^^^^^^^^^^ help: a constant with a similar name exists: `IP_RECVIF`
     |
    ::: /home/h3artbl33d/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.154/src/unix/bsd/netbsdlike/openbsd/mod.rs:1246:1
     |
1246 | pub const IP_RECVIF: ::c_int = 30;
     | ---------------------------- similarly named constant `IP_RECVIF` defined here

Some errors have detailed explanations: E0412, E0425, E0531.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `quinn-udp` (lib) due to 11 previous errors
warning: build failed, waiting for other jobs to finish...
error: failed to compile `deltachat-rpc-server v1.137.4 (https://github.com/deltachat/deltachat-core-rust/#14aaab05)`, intermediate artifacts can be found at `/tmp/cargo-installPQSQeI`.
To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.
@hpk42
Copy link
Contributor

hpk42 commented May 11, 2024

Quinn has a somewhat stale issues on this quinn-rs/quinn#1469 .... This is used by iroh which in turn is used for multi-device setup and (in the future for realtime channels between chat peers). Its otherwise not needed for DC core operations so it could maybe be behind a feature flag.

@link2xt
Copy link
Collaborator

link2xt commented May 11, 2024

The problem is missing libc::IP_RECVTOS, not sendmmsg. sendmmsg is there: https://man.openbsd.org/sendmmsg

But it tries to use syscall which only makes sense for Linux where syscalls are a stable API.

@link2xt link2xt added the bug Something is not working label May 11, 2024
@link2xt
Copy link
Collaborator

link2xt commented May 11, 2024

Documenting what I did on a VM:

  • pkg_add git to clone the repo.
  • pkg_add rust to install Rust 1.77. There is no support from rustup and no official builds of Rust for OpenBSD.
  • pkg_add gmake to build vendored OpenSSL.
  • pkg_add ripgred and pkg_add rust-rustfmt

Added user to staff group with usermod -G staff user and usermod -L staff user, then increased datasize-cur in /etc/login.conf for staff so compilation does not run out of memory.

@link2xt
Copy link
Collaborator

link2xt commented May 11, 2024

I think the way to go is to make quinn-udp build on OpenBSD (i.e. fix quinn-rs/quinn#1469) and then update quinn version we use for iroh 0.4.

@link2xt
Copy link
Collaborator

link2xt commented May 11, 2024

recvmmsg support was only added recently in OpenBSD 7.2 and libc crate is not aware of it yet, I filed an issue: rust-lang/libc#3696

@link2xt
Copy link
Collaborator

link2xt commented May 11, 2024

Short-term fix I am going to hide iroh behind conditional compilation (not feature flag, just make backup transfer always return an error when compiled on OpenBSD).

@link2xt link2xt self-assigned this May 11, 2024
@dignifiedquire
Copy link
Member

Work on the iroh side to get this fixed

@link2xt
Copy link
Collaborator

link2xt commented May 12, 2024

Segmentation fault of test binary trying to run after disabling iroh:

(gdb) r
Starting program: /home/user/link2xt/deltachat-core-rust/target/debug/deps/deltachat-e5ef9b9e62bfb452
Error while reading shared library symbols:
Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /usr/libexec/ld.so]

running 797 tests
test accounts::tests::test_account_new_open ... ok
test accounts::tests::test_account_new_add_remove ... ok
test accounts::tests::test_accounts_remove_last ... ok
test accounts::tests::test_account_new_open_conflict ... ok

Program received signal SIGSEGV, Segmentation fault.
[Switching to thread 608841]
sha512_block_data_order_avx2 () at crypto/sha/sha512-x86_64.s:4139
4139	crypto/sha/sha512-x86_64.s: No such file or directory.
	in crypto/sha/sha512-x86_64.s
Current language:  auto; currently asm
(gdb) bt
#0  sha512_block_data_order_avx2 () at crypto/sha/sha512-x86_64.s:4139
#1  0x0000098c4379bd11 in SHA512_Update (c=Variable "c" is not available.
) at crypto/sha/sha512.c:317
#2  0x0000098c43726c5a in HMAC_Init_ex (ctx=Variable "ctx" is not available.
) at crypto/hmac/hmac.c:79
#3  0x0000098c438b70d0 in kdf_pbkdf2_derive (vctx=Variable "vctx" is not available.
) at providers/implementations/kdfs/pbkdf2.c:353
#4  0x0000098c437135fc in ossl_pkcs5_pbkdf2_hmac_ex (pass=Variable "pass" is not available.
) at crypto/evp/p5_crpt2.c:60
#5  0x0000098c43713675 in PKCS5_PBKDF2_HMAC (pass=Variable "pass" is not available.
) at crypto/evp/p5_crpt2.c:87
#6  0x0000098c43531bb8 in sqlcipher_openssl_kdf (algorithm=Variable "algorithm" is not available.
) at sqlcipher/sqlite3.c:106114
#7  0x0000098c43530bcf in sqlcipher_cipher_ctx_key_derive (ctx=Variable "ctx" is not available.
) at sqlcipher/sqlite3.c:104552
#8  0x0000098c4353095a in sqlcipher_codec_key_derive (ctx=Variable "ctx" is not available.
) at sqlcipher/sqlite3.c:104604
#9  0x0000098c4352e432 in sqlite3Codec (iCtx=Variable "iCtx" is not available.
) at sqlcipher/sqlite3.c:102824
#10 0x0000098c43542fe6 in pager_write_pagelist (pPager=Variable "pPager" is not available.
) at sqlcipher/sqlite3.c:58549
#11 0x0000098c43525b13 in sqlite3PagerCommitPhaseOne (pPager=Variable "pPager" is not available.
) at sqlcipher/sqlite3.c:60722
#12 0x0000098c43525d34 in sqlite3BtreeCommitPhaseOne (p=Variable "p" is not available.
) at sqlcipher/sqlite3.c:71331
#13 0x0000098c43549df5 in sqlite3VdbeHalt (p=Variable "p" is not available.
) at sqlcipher/sqlite3.c:83889
#14 0x0000098c43555155 in sqlite3VdbeExec (p=Variable "p" is not available.
) at sqlcipher/sqlite3.c:89923
#15 0x0000098c43523113 in sqlite3_step (pStmt=Variable "pStmt" is not available.
) at sqlcipher/sqlite3.c:87100
#16 0x0000098c43515ee3 in _ZN8rusqlite10Connection13execute_batch17h386a2b465d4b3431E () at raw_statement.rs:106
#17 0x0000098c42693e8b in _ZN8rusqlite6pragma38_$LT$impl$u20$rusqlite..Connection$GT$13pragma_update17h2b071e0d4cc0d0c6E () at pragma.rs:270
#18 0x0000098c426966a8 in _ZN9deltachat3sql14new_connection17h7267efe88618b3c0E () at sql.rs:700
#19 0x0000098c42695d85 in _ZN9deltachat3sql3Sql8new_pool17h07660a7823a05d61E () at sql.rs:186
#20 0x0000098c42c6b4cf in _ZN9deltachat3sql3Sql8try_open28_$u7b$$u7b$closure$u7d$$u7d$17hd61906c6f9bd4109E () at sql.rs:195
#21 0x0000098c42c6e8c6 in _ZN9deltachat3sql3Sql4open28_$u7b$$u7b$closure$u7d$$u7d$17h49e1961ba7d400ecE () at sql.rs:290
#22 0x0000098c42f74ef2 in _ZN9deltachat7context7Context4open28_$u7b$$u7b$closure$u7d$$u7d$17hbaab2ec0182697fbE () at context.rs:378
#23 0x0000098c41ea3e6c in _ZN9deltachat8accounts5tests22test_encrypted_account28_$u7b$$u7b$closure$u7d$$u7d$17h2dd2bce7d85666bfE () at accounts.rs:957
#24 0x0000098c42606bff in _ZN72_$LT$core..pin..Pin$LT$P$GT$$u20$as$u20$core..future..future..Future$GT$4poll17h8b212170e807c74cE () at future.rs:124
#25 0x0000098c42c56b62 in _ZN5tokio7runtime4park16CachedParkThread8block_on28_$u7b$$u7b$closure$u7d$$u7d$17h5369daeb39dde537E () at park.rs:281
#26 0x0000098c42c565a5 in _ZN5tokio7runtime4park16CachedParkThread8block_on17hf0955bafbfcfc934E () at coop.rs:107
#27 0x0000098c41d9760e in _ZN5tokio7runtime7context8blocking19BlockingRegionGuard8block_on17he090172519ab2a8dE () at blocking.rs:66
#28 0x0000098c42aee83f in _ZN5tokio7runtime9scheduler12multi_thread11MultiThread8block_on28_$u7b$$u7b$closure$u7d$$u7d$17h805983381f623028E () at mod.rs:87
#29 0x0000098c41b5987a in _ZN5tokio7runtime7context7runtime13enter_runtime17he68e896d58c921e3E () at runtime.rs:65
#30 0x0000098c42aee788 in _ZN5tokio7runtime9scheduler12multi_thread11MultiThread8block_on17hd19021d98aea220cE () at mod.rs:86
#31 0x0000098c41b5ac1a in _ZN5tokio7runtime7runtime7Runtime8block_on17hcc229c9fc1b1a7c2E () at runtime.rs:351
#32 0x0000098c41b61b19 in _ZN9deltachat8accounts5tests22test_encrypted_account17h2bc7b3782fad5e6bE () at accounts.rs:978
#33 0x0000098c41ea33c9 in _ZN9deltachat8accounts5tests22test_encrypted_account28_$u7b$$u7b$closure$u7d$$u7d$17hc65929151051f629E () at accounts.rs:937
#34 0x0000098c418e99ac in _ZN4core3ops8function6FnOnce9call_once17h235766f453eb28edE () at function.rs:250
#35 0x0000098c430df5b7 in test::__rust_begin_short_backtrace::hbaadcb723cb5b710 () at result.rs:1959
#36 0x0000098c430f3d58 in test::types::RunnableTest::run::h0e862da4cb07f5fb () at result.rs:1959
#37 0x0000098c430df778 in test::run_test_in_process::h735a0456eab16c8e () at result.rs:1959
#38 0x0000098c430e92ec in std::sys_common::backtrace::__rust_begin_short_backtrace::h73adbab8f80b1d53 () at result.rs:1959
#39 0x0000098c4311c6cd in core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h923b1a7995c70caa () at result.rs:1959
#40 0x0000098c438e9c2d in std::sys::pal::unix::thread::Thread::new::thread_start::h2580486cfabf0af3 () from /home/user/link2xt/deltachat-core-rust/target/debug/deps/deltachat-e5ef9b9e62bfb452
#41 0x0000098ef8512282 in _rthread_start (v=Unhandled dwarf expression opcode 0xa3
) at /usr/src/lib/librthread/rthread.c:96
#42 0x0000098e716327ba in __tfork_thread () at /usr/src/lib/libc/arch/amd64/sys/tfork_thread.S:87
#43 0x0000098e716327ba in __tfork_thread () at /usr/src/lib/libc/arch/amd64/sys/tfork_thread.S:87
Previous frame identical to this frame (corrupt stack?)

I think the problem is not SQLCipher vs SQLite, but race condition between using the connection and tearing it down from another thread. Likely a bug in unsafe code of rusqlite. I am pretty sure it is not the cryptography itself (SHA512 etc.) that is failing, so switching from SQLCipher to SQLite does not make much sense IMO.

@dignifiedquire
Copy link
Member

crypto/sha/sha512-x86_64.s: No such file or directory.

I don't think it is a race condition, but rather a compile issue in the vendored version of deltachat. Everything works fine when disabling the vendoring

@link2xt
Copy link
Collaborator

link2xt commented May 13, 2024

What is the problem with vendored version of SQLCipher? It is the same version 4.5.6 as in the ports tree. Maybe compilation flags are different, OpenBSD ones are here:
https://github.com/openbsd/ports/blob/f325df573d683382c2119c03d710d07d95333365/databases/sqlcipher/Makefile#L28

"No such file or directory" just says that source code is not found by gdb.

sqlite3_step segfaulting looks like use-after-free for me.

I have minimized segfault to this:

use std::error::Error;
use std::fs;

use rusqlite::{Connection, OpenFlags};

fn main() -> Result<(), Box<dyn Error>> {
    fs::remove_file("foobar.db").ok();
    let conn = Connection::open_with_flags(
        "foobar.db",
        OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE,
    )?;
    conn.pragma_update(None, "key", "foobar")?;
    conn.execute("CREATE TABLE foo (bar INTEGER)", ())?;

    Ok(())
}

Corresponding Cargo.toml:

[package]
name = "minmalsegfault"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rusqlite = { version = "0.31.0", features = ["sqlcipher", "bundled-sqlcipher-vendored-openssl"] }

It does not segfault if bundled-sqlcipher-vendored-openssl feature is removed or replaced with bundled-sqlcipher.

It also does not segfault if I run it under lldb, and then does not segfault if I run it directly as target/debug/minimalsegfault, but starts segfaulting again if I remove target/debug/minimalsegfault and rebuild it:

deltachat$ sha256 target/debug/minmalsegfault
SHA256 (target/debug/minmalsegfault) = 473a948649749621cddd7dc27316323b6e99d9019de079bfaecb5c72b633ac41
deltachat$ target/debug/minmalsegfault
Segmentation fault (core dumped)
deltachat$ lldb target/debug/minmalsegfault
(lldb) target create "target/debug/minmalsegfault"
Current executable set to '/home/user/link2xt/minmalsegfault/target/debug/minmalsegfault' (x86_64).
(lldb) r
Process 81083 launched: '/home/user/link2xt/minmalsegfault/target/debug/minmalsegfault' (x86_64)
Process 81083 exited with status = 0 (0x00000000)
(lldb) ^D
deltachat$ target/debug/minmalsegfault
deltachat$ target/debug/minmalsegfault
deltachat$ rm target/debug/minmalsegfault
deltachat$ cargo build
    Finished dev [unoptimized + debuginfo] target(s) in 0.37s
deltachat$ sha256 target/debug/minmalsegfault
SHA256 (target/debug/minmalsegfault) = 473a948649749621cddd7dc27316323b6e99d9019de079bfaecb5c72b633ac41
deltachat$ target/debug/minmalsegfault
Segmentation fault (core dumped)

Backtrace from gdb:

(gdb) r
Starting program: /home/user/link2xt/minmalsegfault/target/debug/minmalsegfault
Error while reading shared library symbols:
Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /usr/libexec/ld.so]

Program received signal SIGSEGV, Segmentation fault.
aesni_set_encrypt_key () at crypto/aes/aesni-x86_64.s:4326
4326	crypto/aes/aesni-x86_64.s: No such file or directory.
	in crypto/aes/aesni-x86_64.s
Current language:  auto; currently asm
(gdb) bt
#0  aesni_set_encrypt_key () at crypto/aes/aesni-x86_64.s:4326
#1  0x00000a2ed092b5ad in cipher_hw_aesni_initkey (dat=Variable "dat" is not available.
) at cipher_aes_hw_aesni.inc:37
#2  0x00000a2ed098af48 in cipher_generic_init_internal (ctx=Variable "ctx" is not available.
) at providers/implementations/ciphers/ciphercommon.c:221
#3  0x00000a2ed098ae12 in ossl_cipher_generic_einit (vctx=Variable "vctx" is not available.
) at providers/implementations/ciphers/ciphercommon.c:232
#4  0x00000a2ed07234b1 in evp_cipher_init_internal (ctx=Variable "ctx" is not available.
) at refcount.h:52
#5  0x00000a2ed0723613 in EVP_CipherInit_ex (ctx=Variable "ctx" is not available.
) at crypto/evp/evp_enc.c:462
#6  0x00000a2ed097685f in drbg_ctr_set_ctx_params_locked (vctx=Variable "vctx" is not available.
) at providers/implementations/rands/drbg_ctr.c:603
#7  0x00000a2ed09744b0 in drbg_ctr_instantiate_wrapper (vdrbg=Variable "vdrbg" is not available.
) at providers/implementations/rands/drbg_ctr.c:341
#8  0x00000a2ed082b774 in EVP_RAND_instantiate (ctx=Variable "ctx" is not available.
) at crypto/evp/evp_rand.c:517
#9  0x00000a2ed082ce8b in rand_new_drbg (libctx=Variable "libctx" is not available.
) at crypto/rand/rand_lib.c:687
#10 0x00000a2ed082c0c1 in RAND_get0_primary (ctx=Variable "ctx" is not available.
) at crypto/rand/rand_lib.c:734
#11 0x00000a2ed082c563 in RAND_get0_public (ctx=Variable "ctx" is not available.
) at crypto/rand/rand_lib.c:765
#12 0x00000a2ed082c484 in RAND_bytes_ex (ctx=Variable "ctx" is not available.
) at crypto/rand/rand_lib.c:378
#13 0x00000a2ed05bfa9f in sqlcipher_openssl_random (ctx=0x0, buffer=0xa31b1fd8748, length=16) at sqlcipher/sqlite3.c:110178
#14 0x00000a2ed05bdbf9 in sqlcipher_codec_ctx_init_kdf_salt (ctx=0xa31b1fe1328) at sqlcipher/sqlite3.c:108411
#15 0x00000a2ed05be679 in sqlcipher_cipher_ctx_key_derive (ctx=0xa31b1fe1328, c_ctx=0xa31b1fcee78) at sqlcipher/sqlite3.c:108790
#16 0x00000a2ed05be4af in sqlcipher_codec_key_derive (ctx=0xa31b1fe1328) at sqlcipher/sqlite3.c:108860
#17 0x00000a2ed05ba54a in sqlite3Codec (iCtx=0xa31b1fe1328, data=0xa3170ca4008, pgno=1, mode=6) at sqlcipher/sqlite3.c:107084
#18 0x00000a2ed05de20b in pager_write_pagelist (pPager=0xa31b1fcda88, pList=0xa3170ca5040) at sqlcipher/sqlite3.c:61135
#19 0x00000a2ed05ab989 in sqlite3PagerCommitPhaseOne (pPager=0xa31b1fcda88, zSuper=0x0, noSync=0) at sqlcipher/sqlite3.c:63319
#20 0x00000a2ed05abdfa in sqlite3BtreeCommitPhaseOne (p=0xa31b1fdf008, zSuperJrnl=0x0) at sqlcipher/sqlite3.c:74361
#21 0x00000a2ed05ecf79 in vdbeCommit (db=0xa31b1ff6388, p=0xa31b1fde508) at sqlcipher/sqlite3.c:87333
#22 0x00000a2ed05ec29e in sqlite3VdbeHalt (p=0xa31b1fde508) at sqlcipher/sqlite3.c:87743
#23 0x00000a2ed05f36a2 in sqlite3VdbeExec (p=0xa31b1fde508) at sqlcipher/sqlite3.c:93895
#24 0x00000a2ed05af4f1 in sqlite3Step (p=0xa31b1fde508) at sqlcipher/sqlite3.c:90705
#25 0x00000a2ed05a8ee8 in sqlite3_step (pStmt=0xa31b1fde508) at sqlcipher/sqlite3.c:90766
#26 0x00000a2ed058a52a in _ZN8rusqlite13raw_statement12RawStatement4step17h1cc4ee59cbbf8421E (self=0x79b39c47bf40) at raw_statement.rs:106
#27 0x00000a2ed058b477 in _ZN8rusqlite9statement9Statement29execute_with_bound_parameters17ha94539f0bfccc097E (self=0x79b39c47bf38) at statement.rs:659
#28 0x00000a2ed058bd63 in _ZN8rusqlite9statement9Statement7execute17h37b2ea6d243471b8E (self=0x79b39c47bf38, params=0) at statement.rs:113
#29 0x00000a2ed058c960 in _ZN8rusqlite10Connection7execute28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17h95289cb346774e2aE () at lib.rs:622
#30 0x00000a2ed058b91c in _ZN4core6result19Result$LT$T$C$E$GT$8and_then17h156c923f2b70eba2E (self=Variable "self" is not available.
) at result.rs:1316
#31 0x00000a2ed058c8ec in _ZN8rusqlite10Connection7execute28_$u7b$$u7b$closure$u7d$$u7d$17h11bc1bbdb057931cE (stmt=Variable "stmt" is not available.
) at lib.rs:622
#32 0x00000a2ed058b9e7 in _ZN4core6result19Result$LT$T$C$E$GT$8and_then17h9c31c7498f85d62bE (self=Variable "self" is not available.
) at result.rs:1316
#33 0x00000a2ed058c85a in _ZN8rusqlite10Connection7execute17h911cbc4321d9f801E (self=0x79b39c47c0d0, sql=
      {data_ptr = 0xa2ed04acd7f "CREATE TABLE foo (bar INTEGER)src/main.rsdescription() is deprecated; use Display�r", length = 30}, params=0) at lib.rs:621
#34 0x00000a2ed058a855 in _ZN14minmalsegfault4main17haa5db2fd92e500efE () at main.rs:14
#35 0x00000a2ed058aeb2 in _ZN4core3ops8function6FnOnce9call_once17hb96fff8ad01e0288E () at function.rs:250
#36 0x00000a2ed058c485 in _ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17hd166fc0a34471332E (f=0xa2ed058a600 <_ZN14minmalsegfault4main17haa5db2fd92e500efE>)
    at backtrace.rs:155
#37 0x00000a2ed058ab18 in _ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17hac38d9a6d186d8e8E () at rt.rs:166
#38 0x00000a2ed09abe29 in std::rt::lang_start_internal::hf9bc85ac22917681 () from /home/user/link2xt/minmalsegfault/target/debug/minmalsegfault
#39 0x00000a2ed058aaec in _ZN3std2rt10lang_start17hb8161abf303dc758E (main=0xa2ed058a600 <_ZN14minmalsegfault4main17haa5db2fd92e500efE>, argc=1, argv=0x79b39c47c698, sigpipe=0 '\0')
    at rt.rs:165
#40 0x00000a2ed058a9f5 in main () at function.rs:249

The most interesting part is here:

#13 0x00000a2ed05bfa9f in sqlcipher_openssl_random (ctx=0x0, buffer=0xa31b1fd8748, length=16) at sqlcipher/sqlite3.c:110178
#14 0x00000a2ed05bdbf9 in sqlcipher_codec_ctx_init_kdf_salt (ctx=0xa31b1fe1328) at sqlcipher/sqlite3.c:108411

In sqlcipher_codec_ctx_init_kdf_salt the code looks like this around line 108411:

    if(ctx->provider->random(ctx->provider_ctx, ctx->kdf_salt, ctx->kdf_salt_sz) != SQLITE_OK) {

Then in the backtrace we see that sqlcipher_openssl_random is called with ctx=0x0 as the first argument, so apparently ctx->provider_ctx was NULL.

So it looks like this provider_ctx initialization failed at some point (probably when setting the key), but connection remains usable in Rust after that, yet segfaults when you try to actually use it. Likely a bug that should be upstreamed to sqlcipher, it should not leave connection in a broken state like this even if setting the key failed.

EDIT: actually it seems that ctx is never set by OpenSSL initialization and sqlcipher_openssl_random does not use it. It is probably only used by different "providers", in case of OpenSSL it is ok to be NULL.

@link2xt
Copy link
Collaborator

link2xt commented May 14, 2024

I have opened upstream issue: rusqlite/rusqlite#1503

@link2xt link2xt removed their assignment May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is not working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants