Repository: tonarino/innernet (language: rust)

Issue:
Segfault at the end of the `innernet-server new` wizard on Alpine Linux
Hi!

I am new to Innernet and wanted to try it out after reading your blogpost. 

I'm using an Alpine Linux VM (`x86_64-alpine-linux-musl`) that I already used as a Wireguard host. After a bit of getting started, I compiled the innernet-server binary with cargo and ran `innernet-server new`. It crashed with a segmentation fault. 

Then I compiled it again with debug flags and ran the valgrind memcheck thing (I'm not a valgrind expert, but GDB didn't show anything obvious)

Here's how I built and ran it:
```
git clone <this repository> && cd innernet
cargo build --bin innernet-server

valgrind --tool=memcheck target/debug/innernet-server new
```

Here's the output:

```
# valgrind --tool=memcheck target/debug/innernet-server new
==10010== Memcheck, a memory error detector
==10010== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10010== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==10010== Command: target/debug/innernet-server new
==10010==

Time to setup your innernet network.

Your network name can be any hostname-valid string, i.e. "evilcorp", and
your network CIDR should be in the RFC1918 IPv4 (10/8, 172.16/12, or 192.168/16),
or RFC4193 IPv6 (fd00::/8) ranges.

The external endpoint specified is a <host>:<port> string that is the address clients
will connect to. It's up to you to forward/open ports in your routers/firewalls
as needed.

For more usage instructions, see https://github.com/tonarino/innernet#usage

==10010== Conditional jump or move depends on uninitialised value(s)
==10010==    at 0xB8CA55: mal0_clear (malloc.c:346)
==10010==    by 0xB8CA55: calloc (malloc.c:364)
==10010==    by 0x886B8B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==10010==    by 0x886D1C: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==10010==    by 0x88823C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==10010==    by 0x898FB1: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==10010==    by 0x8A004C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==10010==    by 0x84221D: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==10010==    by 0x85486A: alloc::vec::from_elem (mod.rs:2423)
==10010==    by 0x83DA39: regex::compile::SuffixCache::new (compile.rs:1121)
==10010==    by 0x8307A7: regex::compile::Compiler::new (compile.rs:65)
==10010==    by 0x81F764: regex::exec::ExecBuilder::build (exec.rs:317)
==10010==    by 0x88373C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==10010==
✔ Network CIDR · 10.42.0.0/16
✔ Listen port · 51880
getting external IP address.
✔ Auto-fill public IP address (via a DNS query to 1.1.1.1)? · no
✔ External endpoint · XXX.YYY.ZZZ.AAA:51880
==10010== Jump to the invalid address stated on the next line
==10010==    at 0x0: ???
==10010==    by 0x6661D6: rusqlite::inner_connection::ensure_safe_sqlite_threading_mode (inner_connection.rs:344)
==10010==    by 0x664DA0: rusqlite::inner_connection::InnerConnection::open_with_flags (inner_connection.rs:68)
==10010==    by 0x2BCCDC: rusqlite::Connection::open_with_flags (lib.rs:400)
==10010==    by 0x2BD3D9: rusqlite::Connection::open (lib.rs:374)
==10010==    by 0x2696A7: innernet_server::initialize::create_database (initialize.rs:18)
==10010==    by 0x39368C: innernet_server::initialize::init_wizard (initialize.rs:196)
==10010==    by 0x2848BB: innernet_server::main::{{closure}} (main.rs:255)
==10010==    by 0x2CBBA9: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (mod.rs:91)
==10010==    by 0x3065BB: tokio::park::thread::CachedParkThread::block_on::{{closure}} (thread.rs:263)
==10010==    by 0x2EA1B9: tokio::coop::with_budget::{{closure}} (coop.rs:102)
==10010==    by 0x38D976: std::thread::local::LocalKey<T>::try_with (local.rs:445)
==10010==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==10010==
==10010==
==10010== Process terminating with default action of signal 11 (SIGSEGV)
==10010==  Bad permissions for mapped region at address 0x0
==10010==    at 0x0: ???
==10010==    by 0x6661D6: rusqlite::inner_connection::ensure_safe_sqlite_threading_mode (inner_connection.rs:344)
==10010==    by 0x664DA0: rusqlite::inner_connection::InnerConnection::open_with_flags (inner_connection.rs:68)
==10010==    by 0x2BCCDC: rusqlite::Connection::open_with_flags (lib.rs:400)
==10010==    by 0x2BD3D9: rusqlite::Connection::open (lib.rs:374)
==10010==    by 0x2696A7: innernet_server::initialize::create_database (initialize.rs:18)
==10010==    by 0x39368C: innernet_server::initialize::init_wizard (initialize.rs:196)
==10010==    by 0x2848BB: innernet_server::main::{{closure}} (main.rs:255)
==10010==    by 0x2CBBA9: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (mod.rs:91)
==10010==    by 0x3065BB: tokio::park::thread::CachedParkThread::block_on::{{closure}} (thread.rs:263)
==10010==    by 0x2EA1B9: tokio::coop::with_budget::{{closure}} (coop.rs:102)
==10010==    by 0x38D976: std::thread::local::LocalKey<T>::try_with (local.rs:445)
==10010==
==10010== HEAP SUMMARY:
==10010==     in use at exit: 0 bytes in 0 blocks
==10010==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==10010==
==10010== All heap blocks were freed -- no leaks are possible
==10010==
==10010== Use --track-origins=yes to see where uninitialised values come from
==10010== For lists of detected and suppressed errors, rerun with: -s
==10010== ERROR SUMMARY: 116 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault
```

Let me know if I can provide more or better information. Oh, and I should say, it creates a conf file in `/etc/innernet-server/` but the directory is otherwise empty:

```pewpew6.conf
# cat /etc/innernet-server/pewpew6.conf
private-key = "XXXYYYZZZXXXYYYZZZXXXYYYZZZ="
listen-port = 51880
address = "10.42.0.1"
network-cidr-prefix = 16
```

Segfault at the end of the `innernet-server new` wizard on Alpine Linux
Hi!

I am new to Innernet and wanted to try it out after reading your blogpost. 

I'm using an Alpine Linux VM (`x86_64-alpine-linux-musl`) that I already used as a Wireguard host. After a bit of getting started, I compiled the innernet-server binary with cargo and ran `innernet-server new`. It crashed with a segmentation fault. 

Then I compiled it again with debug flags and ran the valgrind memcheck thing (I'm not a valgrind expert, but GDB didn't show anything obvious)

Here's how I built and ran it:
```
git clone <this repository> && cd innernet
cargo build --bin innernet-server

valgrind --tool=memcheck target/debug/innernet-server new
```

Here's the output:

```
# valgrind --tool=memcheck target/debug/innernet-server new
==10010== Memcheck, a memory error detector
==10010== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10010== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==10010== Command: target/debug/innernet-server new
==10010==

Time to setup your innernet network.

Your network name can be any hostname-valid string, i.e. "evilcorp", and
your network CIDR should be in the RFC1918 IPv4 (10/8, 172.16/12, or 192.168/16),
or RFC4193 IPv6 (fd00::/8) ranges.

The external endpoint specified is a <host>:<port> string that is the address clients
will connect to. It's up to you to forward/open ports in your routers/firewalls
as needed.

For more usage instructions, see https://github.com/tonarino/innernet#usage

==10010== Conditional jump or move depends on uninitialised value(s)
==10010==    at 0xB8CA55: mal0_clear (malloc.c:346)
==10010==    by 0xB8CA55: calloc (malloc.c:364)
==10010==    by 0x886B8B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==10010==    by 0x886D1C: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==10010==    by 0x88823C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==10010==    by 0x898FB1: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==10010==    by 0x8A004C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==10010==    by 0x84221D: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==10010==    by 0x85486A: alloc::vec::from_elem (mod.rs:2423)
==10010==    by 0x83DA39: regex::compile::SuffixCache::new (compile.rs:1121)
==10010==    by 0x8307A7: regex::compile::Compiler::new (compile.rs:65)
==10010==    by 0x81F764: regex::exec::ExecBuilder::build (exec.rs:317)
==10010==    by 0x88373C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==10010==
✔ Network CIDR · 10.42.0.0/16
✔ Listen port · 51880
getting external IP address.
✔ Auto-fill public IP address (via a DNS query to 1.1.1.1)? · no
✔ External endpoint · XXX.YYY.ZZZ.AAA:51880
==10010== Jump to the invalid address stated on the next line
==10010==    at 0x0: ???
==10010==    by 0x6661D6: rusqlite::inner_connection::ensure_safe_sqlite_threading_mode (inner_connection.rs:344)
==10010==    by 0x664DA0: rusqlite::inner_connection::InnerConnection::open_with_flags (inner_connection.rs:68)
==10010==    by 0x2BCCDC: rusqlite::Connection::open_with_flags (lib.rs:400)
==10010==    by 0x2BD3D9: rusqlite::Connection::open (lib.rs:374)
==10010==    by 0x2696A7: innernet_server::initialize::create_database (initialize.rs:18)
==10010==    by 0x39368C: innernet_server::initialize::init_wizard (initialize.rs:196)
==10010==    by 0x2848BB: innernet_server::main::{{closure}} (main.rs:255)
==10010==    by 0x2CBBA9: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (mod.rs:91)
==10010==    by 0x3065BB: tokio::park::thread::CachedParkThread::block_on::{{closure}} (thread.rs:263)
==10010==    by 0x2EA1B9: tokio::coop::with_budget::{{closure}} (coop.rs:102)
==10010==    by 0x38D976: std::thread::local::LocalKey<T>::try_with (local.rs:445)
==10010==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==10010==
==10010==
==10010== Process terminating with default action of signal 11 (SIGSEGV)
==10010==  Bad permissions for mapped region at address 0x0
==10010==    at 0x0: ???
==10010==    by 0x6661D6: rusqlite::inner_connection::ensure_safe_sqlite_threading_mode (inner_connection.rs:344)
==10010==    by 0x664DA0: rusqlite::inner_connection::InnerConnection::open_with_flags (inner_connection.rs:68)
==10010==    by 0x2BCCDC: rusqlite::Connection::open_with_flags (lib.rs:400)
==10010==    by 0x2BD3D9: rusqlite::Connection::open (lib.rs:374)
==10010==    by 0x2696A7: innernet_server::initialize::create_database (initialize.rs:18)
==10010==    by 0x39368C: innernet_server::initialize::init_wizard (initialize.rs:196)
==10010==    by 0x2848BB: innernet_server::main::{{closure}} (main.rs:255)
==10010==    by 0x2CBBA9: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (mod.rs:91)
==10010==    by 0x3065BB: tokio::park::thread::CachedParkThread::block_on::{{closure}} (thread.rs:263)
==10010==    by 0x2EA1B9: tokio::coop::with_budget::{{closure}} (coop.rs:102)
==10010==    by 0x38D976: std::thread::local::LocalKey<T>::try_with (local.rs:445)
==10010==
==10010== HEAP SUMMARY:
==10010==     in use at exit: 0 bytes in 0 blocks
==10010==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==10010==
==10010== All heap blocks were freed -- no leaks are possible
==10010==
==10010== Use --track-origins=yes to see where uninitialised values come from
==10010== For lists of detected and suppressed errors, rerun with: -s
==10010== ERROR SUMMARY: 116 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault
```

Let me know if I can provide more or better information. Oh, and I should say, it creates a conf file in `/etc/innernet-server/` but the directory is otherwise empty:

```pewpew6.conf
# cat /etc/innernet-server/pewpew6.conf
private-key = "XXXYYYZZZXXXYYYZZZXXXYYYZZZ="
listen-port = 51880
address = "10.42.0.1"
network-cidr-prefix = 16
```



Discussion / hints:
Hi @hellerbarde, thanks for the report.

The `inner_connection.rs:344` is this line of code https://github.com/rusqlite/rusqlite/blob/v0.27.0/src/inner_connection.rs#L344
```rust
    if unsafe { ffi::sqlite3_threadsafe() == 0 } {
```

The `unsafe {}` explains why this is allowed to segfault. Beyond that I don't have a real clue what's going on.

I've realized that we're not using the latest version of rusqlite and libsqlite-sys, so I've filled #229 to update them. Could you please try with that branch?  (I haven't really found an indication the new version would fix something related however)

If the problem persists, please have a look into various ways rusqlite can bundle (or not) the sqlite library, I suspect that might be the culprit. I've seen some reports of linking errors w.r.t. the `sqlite3_threadsafe()` function. Please also feel free to report this upstream to rusqlite if you're comfortable with that.
Thank you very much for your speedy answer and attempt at resolution. I really appreciate it!

Unfortunately, the problem persists. I can't quite tell if it's the same exact problem, so I attached the Valgrind output below. I will try to file a bug at rusqlite.

```
~/build/innernet# valgrind --tool=memcheck target/debug/innernet-server new
==13573== Memcheck, a memory error detector
==13573== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13573== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==13573== Command: target/debug/innernet-server new
==13573==

Time to setup your innernet network.

Your network name can be any hostname-valid string, i.e. "evilcorp", and
your network CIDR should be in the RFC1918 IPv4 (10/8, 172.16/12, or 192.168/16),
or RFC4193 IPv6 (fd00::/8) ranges.

The external endpoint specified is a <host>:<port> string that is the address clients
will connect to. It's up to you to forward/open ports in your routers/firewalls
as needed.

For more usage instructions, see https://github.com/tonarino/innernet#usage

==13573== Conditional jump or move depends on uninitialised value(s)
==13573==    at 0xBB6E85: mal0_clear (malloc.c:346)
==13573==    by 0xBB6E85: calloc (malloc.c:364)
==13573==    by 0x56418B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13573==    by 0x56431C: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13573==    by 0x56583C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13573==    by 0x4F2361: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13573==    by 0x4F80CC: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13573==    by 0x51F9ED: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13573==    by 0x531DFA: alloc::vec::from_elem (mod.rs:2423)
==13573==    by 0x51B0A9: regex::compile::SuffixCache::new (compile.rs:1118)
==13573==    by 0x50DFA7: regex::compile::Compiler::new (compile.rs:65)
==13573==    by 0x4FCDC4: regex::exec::ExecBuilder::build (exec.rs:317)
==13573==    by 0x560D3C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13573==
✔ Network name · test1
✔ Network CIDR · 10.42.0.0/16
✔ Listen port · 51825
getting external IP address.
✔ Auto-fill public IP address (via a DNS query to 1.1.1.1)? · no
✔ External endpoint · X.Y.Z.A:51825
==13573== Jump to the invalid address stated on the next line
==13573==    at 0x0: ???
==13573==    by 0x7F7E86: rusqlite::inner_connection::ensure_safe_sqlite_threading_mode (inner_connection.rs:404)
==13573==    by 0x7F6A90: rusqlite::inner_connection::InnerConnection::open_with_flags (inner_connection.rs:68)
==13573==    by 0x2F135C: rusqlite::Connection::open_with_flags (lib.rs:433)
==13573==    by 0x2F1805: rusqlite::Connection::open (lib.rs:407)
==13573==    by 0x2C2597: innernet_server::initialize::create_database (initialize.rs:18)
==13573==    by 0x38347C: innernet_server::initialize::init_wizard (initialize.rs:196)
==13573==    by 0x2450AB: innernet_server::main::{{closure}} (main.rs:255)
==13573==    by 0x38F779: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (mod.rs:91)
==13573==    by 0x263DCB: tokio::park::thread::CachedParkThread::block_on::{{closure}} (thread.rs:263)
==13573==    by 0x2632A9: tokio::coop::with_budget::{{closure}} (coop.rs:102)
==13573==    by 0x30F5D6: std::thread::local::LocalKey<T>::try_with (local.rs:445)
==13573==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==13573==
==13573==
==13573== Process terminating with default action of signal 11 (SIGSEGV)
==13573==  Bad permissions for mapped region at address 0x0
==13573==    at 0x0: ???
==13573==    by 0x7F7E86: rusqlite::inner_connection::ensure_safe_sqlite_threading_mode (inner_connection.rs:404)
==13573==    by 0x7F6A90: rusqlite::inner_connection::InnerConnection::open_with_flags (inner_connection.rs:68)
==13573==    by 0x2F135C: rusqlite::Connection::open_with_flags (lib.rs:433)
==13573==    by 0x2F1805: rusqlite::Connection::open (lib.rs:407)
==13573==    by 0x2C2597: innernet_server::initialize::create_database (initialize.rs:18)
==13573==    by 0x38347C: innernet_server::initialize::init_wizard (initialize.rs:196)
==13573==    by 0x2450AB: innernet_server::main::{{closure}} (main.rs:255)
==13573==    by 0x38F779: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (mod.rs:91)
==13573==    by 0x263DCB: tokio::park::thread::CachedParkThread::block_on::{{closure}} (thread.rs:263)
==13573==    by 0x2632A9: tokio::coop::with_budget::{{closure}} (coop.rs:102)
==13573==    by 0x30F5D6: std::thread::local::LocalKey<T>::try_with (local.rs:445)
==13573==
==13573== HEAP SUMMARY:
==13573==     in use at exit: 0 bytes in 0 blocks
==13573==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==13573==
==13573== All heap blocks were freed -- no leaks are possible
==13573==
==13573== Use --track-origins=yes to see where uninitialised values come from
==13573== For lists of detected and suppressed errors, rerun with: -s
==13573== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault
```
I have tried something else you mentioned:

I changed `server/Cargo.toml` to use this dependency line for [rusqlite](https://github.com/rusqlite/rusqlite) like they mention on their README.md.
```
rusqlite = { version = "0.28", features = ["bundled"] }
```

And with that it seems to work, I think. I will try to file a report and link back to this issue. 
and just for completeness sake, this is the valgrind output when it worked:
<details>
<summary><b>Valgrind Output</b></summary>


```
build/innernet# valgrind --tool=memcheck target/debug/innernet-server new
==13961== Memcheck, a memory error detector
==13961== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13961== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==13961== Command: target/debug/innernet-server new
==13961==

Time to setup your innernet network.

Your network name can be any hostname-valid string, i.e. "evilcorp", and
your network CIDR should be in the RFC1918 IPv4 (10/8, 172.16/12, or 192.168/16),
or RFC4193 IPv6 (fd00::/8) ranges.

The external endpoint specified is a <host>:<port> string that is the address clients
will connect to. It's up to you to forward/open ports in your routers/firewalls
as needed.

For more usage instructions, see https://github.com/tonarino/innernet#usage

==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCEEA15: mal0_clear (malloc.c:346)
==13961==    by 0xCEEA15: calloc (malloc.c:364)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
✔ Network name · test2
✔ Network CIDR · 10.42.0.0/16
✔ Listen port · 51826
getting external IP address.
✔ Auto-fill public IP address (via a DNS query to 1.1.1.1)? · no
✔ External endpoint · X.Y.Z.A:51826
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCF53B3: ??? (memset.s:9)
==13961==    by 0xCEE9E1: mal0_clear (malloc.c:343)
==13961==    by 0xCEE9E1: calloc (malloc.c:364)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCF53B7: ??? (memset.s:12)
==13961==    by 0xCEE9E1: mal0_clear (malloc.c:343)
==13961==    by 0xCEE9E1: calloc (malloc.c:364)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCEE9EF: mal0_clear (malloc.c:344)
==13961==    by 0xCEE9EF: calloc (malloc.c:364)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCF53B3: ??? (memset.s:9)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
==13961== Use of uninitialised value of size 8
==13961==    at 0xCF5436: ??? (memset.s:55)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCF5444: ??? (memset.s:60)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0x566845: <usize as core::slice::index::SliceIndex<[T]>>::get (index.rs:209)
==13961==    by 0x5149E6: core::slice::<impl [T]>::get (mod.rs:343)
==13961==    by 0x521DDE: regex::compile::SuffixCache::get (compile.rs:1126)
==13961==    by 0x5213C5: regex::compile::CompileClass::c_utf8_seq_ (compile.rs:1048)
==13961==    by 0x521215: regex::compile::CompileClass::c_utf8_seq (compile.rs:1029)
==13961==    by 0x520C47: regex::compile::CompileClass::compile (compile.rs:1014)
==13961==    by 0x518EE6: regex::compile::Compiler::c_class (compile.rs:462)
==13961==    by 0x517E0B: regex::compile::Compiler::c (compile.rs:280)
==13961==    by 0x51A02F: regex::compile::Compiler::c_concat (compile.rs:525)
==13961==    by 0x5173F4: regex::compile::Compiler::c (compile.rs:384)
==13961==    by 0x517FF2: regex::compile::Compiler::c_capture (compile.rs:410)
==13961==    by 0x5177A6: regex::compile::Compiler::c (compile.rs:369)
==13961==
[*] Created database at /var/lib/innernet-server/test2.db

[*] Setup finished.

    Network test2 has been created, but it's not started yet!

    Your new network starts with only one peer: this innernet server. Next,
    you'll want to create additional CIDRs and peers using the commands:

        innernet-server add-cidr test2, and
        innernet-server add-peer test2

    See https://github.com/tonarino/innernet for more detailed instruction
    on designing your network.

    When you're ready to start the network, you can auto-start the server:

        systemctl enable --now innernet-server@test2

==13961==
==13961== HEAP SUMMARY:
==13961==     in use at exit: 0 bytes in 0 blocks
==13961==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==13961==
==13961== All heap blocks were freed -- no leaks are possible
==13961==
==13961== Use --track-origins=yes to see where uninitialised values come from
==13961== For lists of detected and suppressed errors, rerun with: -s
==13961== ERROR SUMMARY: 2132 errors from 8 contexts (suppressed: 0 from 0)
```
</details>
I found a potentially related issue in the rusqlite repository: https://github.com/rusqlite/rusqlite/issues/914

The proposed workaround (or fix?) is to bundle-compile the library. 
A proposed change, scoped to only target_env="musl": 

```
# git diff
diff --git a/server/Cargo.toml b/server/Cargo.toml
index 255c57d..22d0f0c 100644
--- a/server/Cargo.toml
+++ b/server/Cargo.toml
@@ -47,6 +47,9 @@ wireguard-control = { path = "../wireguard-control" }
 [target.'cfg(target_os = "linux")'.dependencies]
 socket2 = { version = "0.4", features = ["all"] }

+[target.'cfg(target_env = "musl")'.dependencies]
+rusqlite = { version = "0.28", features = ["bundled"] }
+
 [dev-dependencies]
 anyhow = "1"
 tempfile = "3"

```
Thanks @hellerbarde for all the investigation. It indeed looks like an occurrence of rusqlite/rusqlite#914.

I'm inclined to apply your proposed work-around.

Another alternative would be to introduce e.g. a `bundled-sqlite` Cargo feature flag and let users toggle that (i.e. to reproduce this issue). But not sure if that pulls its own weight.

@mcginty do you have any opinions on this?
Hi @hellerbarde, thanks for the report.

The `inner_connection.rs:344` is this line of code https://github.com/rusqlite/rusqlite/blob/v0.27.0/src/inner_connection.rs#L344
```rust
    if unsafe { ffi::sqlite3_threadsafe() == 0 } {
```

The `unsafe {}` explains why this is allowed to segfault. Beyond that I don't have a real clue what's going on.

I've realized that we're not using the latest version of rusqlite and libsqlite-sys, so I've filled #229 to update them. Could you please try with that branch?  (I haven't really found an indication the new version would fix something related however)

If the problem persists, please have a look into various ways rusqlite can bundle (or not) the sqlite library, I suspect that might be the culprit. I've seen some reports of linking errors w.r.t. the `sqlite3_threadsafe()` function. Please also feel free to report this upstream to rusqlite if you're comfortable with that.
Thank you very much for your speedy answer and attempt at resolution. I really appreciate it!

Unfortunately, the problem persists. I can't quite tell if it's the same exact problem, so I attached the Valgrind output below. I will try to file a bug at rusqlite.

```
~/build/innernet# valgrind --tool=memcheck target/debug/innernet-server new
==13573== Memcheck, a memory error detector
==13573== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13573== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==13573== Command: target/debug/innernet-server new
==13573==

Time to setup your innernet network.

Your network name can be any hostname-valid string, i.e. "evilcorp", and
your network CIDR should be in the RFC1918 IPv4 (10/8, 172.16/12, or 192.168/16),
or RFC4193 IPv6 (fd00::/8) ranges.

The external endpoint specified is a <host>:<port> string that is the address clients
will connect to. It's up to you to forward/open ports in your routers/firewalls
as needed.

For more usage instructions, see https://github.com/tonarino/innernet#usage

==13573== Conditional jump or move depends on uninitialised value(s)
==13573==    at 0xBB6E85: mal0_clear (malloc.c:346)
==13573==    by 0xBB6E85: calloc (malloc.c:364)
==13573==    by 0x56418B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13573==    by 0x56431C: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13573==    by 0x56583C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13573==    by 0x4F2361: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13573==    by 0x4F80CC: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13573==    by 0x51F9ED: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13573==    by 0x531DFA: alloc::vec::from_elem (mod.rs:2423)
==13573==    by 0x51B0A9: regex::compile::SuffixCache::new (compile.rs:1118)
==13573==    by 0x50DFA7: regex::compile::Compiler::new (compile.rs:65)
==13573==    by 0x4FCDC4: regex::exec::ExecBuilder::build (exec.rs:317)
==13573==    by 0x560D3C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13573==
✔ Network name · test1
✔ Network CIDR · 10.42.0.0/16
✔ Listen port · 51825
getting external IP address.
✔ Auto-fill public IP address (via a DNS query to 1.1.1.1)? · no
✔ External endpoint · X.Y.Z.A:51825
==13573== Jump to the invalid address stated on the next line
==13573==    at 0x0: ???
==13573==    by 0x7F7E86: rusqlite::inner_connection::ensure_safe_sqlite_threading_mode (inner_connection.rs:404)
==13573==    by 0x7F6A90: rusqlite::inner_connection::InnerConnection::open_with_flags (inner_connection.rs:68)
==13573==    by 0x2F135C: rusqlite::Connection::open_with_flags (lib.rs:433)
==13573==    by 0x2F1805: rusqlite::Connection::open (lib.rs:407)
==13573==    by 0x2C2597: innernet_server::initialize::create_database (initialize.rs:18)
==13573==    by 0x38347C: innernet_server::initialize::init_wizard (initialize.rs:196)
==13573==    by 0x2450AB: innernet_server::main::{{closure}} (main.rs:255)
==13573==    by 0x38F779: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (mod.rs:91)
==13573==    by 0x263DCB: tokio::park::thread::CachedParkThread::block_on::{{closure}} (thread.rs:263)
==13573==    by 0x2632A9: tokio::coop::with_budget::{{closure}} (coop.rs:102)
==13573==    by 0x30F5D6: std::thread::local::LocalKey<T>::try_with (local.rs:445)
==13573==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==13573==
==13573==
==13573== Process terminating with default action of signal 11 (SIGSEGV)
==13573==  Bad permissions for mapped region at address 0x0
==13573==    at 0x0: ???
==13573==    by 0x7F7E86: rusqlite::inner_connection::ensure_safe_sqlite_threading_mode (inner_connection.rs:404)
==13573==    by 0x7F6A90: rusqlite::inner_connection::InnerConnection::open_with_flags (inner_connection.rs:68)
==13573==    by 0x2F135C: rusqlite::Connection::open_with_flags (lib.rs:433)
==13573==    by 0x2F1805: rusqlite::Connection::open (lib.rs:407)
==13573==    by 0x2C2597: innernet_server::initialize::create_database (initialize.rs:18)
==13573==    by 0x38347C: innernet_server::initialize::init_wizard (initialize.rs:196)
==13573==    by 0x2450AB: innernet_server::main::{{closure}} (main.rs:255)
==13573==    by 0x38F779: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll (mod.rs:91)
==13573==    by 0x263DCB: tokio::park::thread::CachedParkThread::block_on::{{closure}} (thread.rs:263)
==13573==    by 0x2632A9: tokio::coop::with_budget::{{closure}} (coop.rs:102)
==13573==    by 0x30F5D6: std::thread::local::LocalKey<T>::try_with (local.rs:445)
==13573==
==13573== HEAP SUMMARY:
==13573==     in use at exit: 0 bytes in 0 blocks
==13573==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==13573==
==13573== All heap blocks were freed -- no leaks are possible
==13573==
==13573== Use --track-origins=yes to see where uninitialised values come from
==13573== For lists of detected and suppressed errors, rerun with: -s
==13573== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault
```
I have tried something else you mentioned:

I changed `server/Cargo.toml` to use this dependency line for [rusqlite](https://github.com/rusqlite/rusqlite) like they mention on their README.md.
```
rusqlite = { version = "0.28", features = ["bundled"] }
```

And with that it seems to work, I think. I will try to file a report and link back to this issue. 
and just for completeness sake, this is the valgrind output when it worked:
<details>
<summary><b>Valgrind Output</b></summary>


```
build/innernet# valgrind --tool=memcheck target/debug/innernet-server new
==13961== Memcheck, a memory error detector
==13961== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13961== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==13961== Command: target/debug/innernet-server new
==13961==

Time to setup your innernet network.

Your network name can be any hostname-valid string, i.e. "evilcorp", and
your network CIDR should be in the RFC1918 IPv4 (10/8, 172.16/12, or 192.168/16),
or RFC4193 IPv6 (fd00::/8) ranges.

The external endpoint specified is a <host>:<port> string that is the address clients
will connect to. It's up to you to forward/open ports in your routers/firewalls
as needed.

For more usage instructions, see https://github.com/tonarino/innernet#usage

==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCEEA15: mal0_clear (malloc.c:346)
==13961==    by 0xCEEA15: calloc (malloc.c:364)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
✔ Network name · test2
✔ Network CIDR · 10.42.0.0/16
✔ Listen port · 51826
getting external IP address.
✔ Auto-fill public IP address (via a DNS query to 1.1.1.1)? · no
✔ External endpoint · X.Y.Z.A:51826
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCF53B3: ??? (memset.s:9)
==13961==    by 0xCEE9E1: mal0_clear (malloc.c:343)
==13961==    by 0xCEE9E1: calloc (malloc.c:364)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCF53B7: ??? (memset.s:12)
==13961==    by 0xCEE9E1: mal0_clear (malloc.c:343)
==13961==    by 0xCEE9E1: calloc (malloc.c:364)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCEE9EF: mal0_clear (malloc.c:344)
==13961==    by 0xCEE9EF: calloc (malloc.c:364)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCF53B3: ??? (memset.s:9)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
==13961== Use of uninitialised value of size 8
==13961==    at 0xCF5436: ??? (memset.s:55)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0xCF5444: ??? (memset.s:60)
==13961==    by 0x56AD5B: alloc::alloc::alloc_zeroed (alloc.rs:160)
==13961==    by 0x56AEEC: alloc::alloc::Global::alloc_impl (alloc.rs:171)
==13961==    by 0x56C40C: <alloc::alloc::Global as core::alloc::Allocator>::allocate_zeroed (alloc.rs:236)
==13961==    by 0x4F8F31: alloc::raw_vec::RawVec<T,A>::allocate_in (raw_vec.rs:186)
==13961==    by 0x4FEC9C: alloc::raw_vec::RawVec<T,A>::with_capacity_zeroed_in (raw_vec.rs:139)
==13961==    by 0x5265BD: <T as alloc::vec::spec_from_elem::SpecFromElem>::from_elem (spec_from_elem.rs:54)
==13961==    by 0x5389CA: alloc::vec::from_elem (mod.rs:2423)
==13961==    by 0x521C79: regex::compile::SuffixCache::new (compile.rs:1118)
==13961==    by 0x514B77: regex::compile::Compiler::new (compile.rs:65)
==13961==    by 0x503994: regex::exec::ExecBuilder::build (exec.rs:317)
==13961==    by 0x56790C: regex::re_builder::unicode::RegexBuilder::build (re_builder.rs:70)
==13961==
==13961== Conditional jump or move depends on uninitialised value(s)
==13961==    at 0x566845: <usize as core::slice::index::SliceIndex<[T]>>::get (index.rs:209)
==13961==    by 0x5149E6: core::slice::<impl [T]>::get (mod.rs:343)
==13961==    by 0x521DDE: regex::compile::SuffixCache::get (compile.rs:1126)
==13961==    by 0x5213C5: regex::compile::CompileClass::c_utf8_seq_ (compile.rs:1048)
==13961==    by 0x521215: regex::compile::CompileClass::c_utf8_seq (compile.rs:1029)
==13961==    by 0x520C47: regex::compile::CompileClass::compile (compile.rs:1014)
==13961==    by 0x518EE6: regex::compile::Compiler::c_class (compile.rs:462)
==13961==    by 0x517E0B: regex::compile::Compiler::c (compile.rs:280)
==13961==    by 0x51A02F: regex::compile::Compiler::c_concat (compile.rs:525)
==13961==    by 0x5173F4: regex::compile::Compiler::c (compile.rs:384)
==13961==    by 0x517FF2: regex::compile::Compiler::c_capture (compile.rs:410)
==13961==    by 0x5177A6: regex::compile::Compiler::c (compile.rs:369)
==13961==
[*] Created database at /var/lib/innernet-server/test2.db

[*] Setup finished.

    Network test2 has been created, but it's not started yet!

    Your new network starts with only one peer: this innernet server. Next,
    you'll want to create additional CIDRs and peers using the commands:

        innernet-server add-cidr test2, and
        innernet-server add-peer test2

    See https://github.com/tonarino/innernet for more detailed instruction
    on designing your network.

    When you're ready to start the network, you can auto-start the server:

        systemctl enable --now innernet-server@test2

==13961==
==13961== HEAP SUMMARY:
==13961==     in use at exit: 0 bytes in 0 blocks
==13961==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==13961==
==13961== All heap blocks were freed -- no leaks are possible
==13961==
==13961== Use --track-origins=yes to see where uninitialised values come from
==13961== For lists of detected and suppressed errors, rerun with: -s
==13961== ERROR SUMMARY: 2132 errors from 8 contexts (suppressed: 0 from 0)
```
</details>
I found a potentially related issue in the rusqlite repository: https://github.com/rusqlite/rusqlite/issues/914

The proposed workaround (or fix?) is to bundle-compile the library. 
A proposed change, scoped to only target_env="musl": 

```
# git diff
diff --git a/server/Cargo.toml b/server/Cargo.toml
index 255c57d..22d0f0c 100644
--- a/server/Cargo.toml
+++ b/server/Cargo.toml
@@ -47,6 +47,9 @@ wireguard-control = { path = "../wireguard-control" }
 [target.'cfg(target_os = "linux")'.dependencies]
 socket2 = { version = "0.4", features = ["all"] }

+[target.'cfg(target_env = "musl")'.dependencies]
+rusqlite = { version = "0.28", features = ["bundled"] }
+
 [dev-dependencies]
 anyhow = "1"
 tempfile = "3"

```
Thanks @hellerbarde for all the investigation. It indeed looks like an occurrence of rusqlite/rusqlite#914.

I'm inclined to apply your proposed work-around.

Another alternative would be to introduce e.g. a `bundled-sqlite` Cargo feature flag and let users toggle that (i.e. to reproduce this issue). But not sure if that pulls its own weight.

@mcginty do you have any opinions on this?

Fix patch:
diff --git a/server/Cargo.toml b/server/Cargo.toml
index 255c57d..22d0f0c 100644
--- a/server/Cargo.toml
+++ b/server/Cargo.toml
@@ -47,6 +47,9 @@ wireguard-control = { path = "../wireguard-control" }
 [target.'cfg(target_os = "linux")'.dependencies]
 socket2 = { version = "0.4", features = ["all"] }
 
+[target.'cfg(target_env = "musl")'.dependencies]
+rusqlite = { version = "0.28", features = ["bundled"] }
+
 [dev-dependencies]
 anyhow = "1"
 tempfile = "3"


Test patch: