Skip to content

Symbol conflicts when static linking to both sqlite3mc + libsodium #229

@jagerman

Description

@jagerman

I am working on a project that uses both sqlite3mc and libsodium, and have run into an issue when doing a static build linking to static libs of both libraries because of identical definitions in the AEGIS code (included in libsodium since 1.0.19, apparently).

Compiling and linking a simple test file that uses and links to static libsodium + sqlite3mc libraries (both are fairly standard static builds) fails with:

$ gcc foo.c -Istatic-deps/include static-deps/lib/libsodium.a static-deps/lib/libsqlite3mc.a -lm
/usr/bin/ld: sqlite3.o (symbol from plugin): in function `sqlite3_temp_directory':
(.text+0x0): multiple definition of `_aes_lut'; libsodium_la-softaes.o (symbol from plugin):(.text+0x0): first defined here
/usr/bin/ld: sqlite3.o (symbol from plugin): in function `sqlite3_temp_directory':
(.text+0x0): multiple definition of `aegis128l_soft_implementation'; libsodium_la-aegis128l_soft.o (symbol from plugin):(.text+0x0): first defined here
/usr/bin/ld: sqlite3.o (symbol from plugin): in function `sqlite3_temp_directory':
(.text+0x0): multiple definition of `aegis128l_aesni_implementation'; libaesni_la-aegis128l_aesni.o (symbol from plugin):(.text+0x0): first defined here
/usr/bin/ld: sqlite3.o (symbol from plugin): in function `sqlite3_temp_directory':
(.text+0x0): multiple definition of `aegis256_soft_implementation'; libsodium_la-aegis256_soft.o (symbol from plugin):(.text+0x0): first defined here
/usr/bin/ld: sqlite3.o (symbol from plugin): in function `sqlite3_temp_directory':
(.text+0x0): multiple definition of `aegis256_aesni_implementation'; libaesni_la-aegis256_aesni.o (symbol from plugin):(.text+0x0): first defined here

foo.c

#include <sodium.h>
#include "sqlite3.h"

int main() {
    if (sodium_init() < 0) return 1;

    sqlite3* db;
    int rc = sqlite3_open("test.db", &db);

    if (rc == SQLITE_OK) {
        // This just to confirm that we are actually using sqlite3mc's API:
        sqlite3mc_config(db, "default:cipher", 0); 
        sqlite3_close(db);
    }
}

I managed to work around the conflict by adding a bunch of compiler definitions (see below) into src/aegis/include/aegis.h to namespace all the AEGIS structs and internal tables inside sqlite3mc's AEGIS implementation to solve the conflicting symbols and let me successfully use libsodium and libsqlite3mc at the same time successfully, but I didn't open a PR with the change because it feels a bit hacky. (That said: I'm a C++ developer, so my feel on what constitutes "hacky C code" is probably a bit off). (Also note: this list was AI generated, after some clearly wrong results that needed prompting to fix, so I would not be at all surprised if this is missing something, though what I have below works for me):

// Namespace aegis structs to avoid linking conflicts with libsodium 1.0.21+:
/* --- Base Implementation Structs --- */
#define aegis128_implementation            mc_aegis128_implementation
#define aegis128l_implementation           mc_aegis128l_implementation
#define aegis256_implementation            mc_aegis256_implementation

/* --- Standard Variants (Soft, AES-NI, VAES, ARM) --- */
#define aegis128_soft_implementation       mc_aegis128_soft_implementation
#define aegis128_aesni_implementation      mc_aegis128_aesni_implementation
#define aegis128_vaes_implementation       mc_aegis128_vaes_implementation
#define aegis128_armcrypto_implementation  mc_aegis128_armcrypto_implementation

#define aegis128l_soft_implementation      mc_aegis128l_soft_implementation
#define aegis128l_aesni_implementation     mc_aegis128l_aesni_implementation
#define aegis128l_vaes_implementation      mc_aegis128l_vaes_implementation
#define aegis128l_armcrypto_implementation mc_aegis128l_armcrypto_implementation

#define aegis256_soft_implementation       mc_aegis256_soft_implementation
#define aegis256_aesni_implementation      mc_aegis256_aesni_implementation
#define aegis256_vaes_implementation       mc_aegis256_vaes_implementation
#define aegis256_armcrypto_implementation  mc_aegis256_armcrypto_implementation

/* --- Parallel Variants (x2, x4) --- */
#define aegis128x2_implementation          mc_aegis128x2_implementation
#define aegis128x4_implementation          mc_aegis128x4_implementation
#define aegis128lx2_implementation         mc_aegis128lx2_implementation
#define aegis128lx4_implementation         mc_aegis128lx4_implementation
#define aegis256x2_implementation          mc_aegis256x2_implementation
#define aegis256x4_implementation          mc_aegis256x4_implementation

/* --- Parallel ISA Providers (AES-NI, VAES, AVX2, AVX512) --- */
#define aegis128x2_aesni_implementation    mc_aegis128x2_aesni_implementation
#define aegis128x2_vaes_implementation     mc_aegis128x2_vaes_implementation
#define aegis128x2_avx2_implementation     mc_aegis128x2_avx2_implementation
#define aegis128x2_avx512_implementation   mc_aegis128x2_avx512_implementation

#define aegis128x4_aesni_implementation    mc_aegis128x4_aesni_implementation
#define aegis128x4_vaes_implementation     mc_aegis128x4_vaes_implementation
#define aegis128x4_avx2_implementation     mc_aegis128x4_avx2_implementation
#define aegis128x4_avx512_implementation   mc_aegis128x4_avx512_implementation

#define aegis128lx2_aesni_implementation   mc_aegis128lx2_aesni_implementation
#define aegis128lx2_vaes_implementation    mc_aegis128lx2_vaes_implementation
#define aegis128lx2_avx2_implementation    mc_aegis128lx2_avx2_implementation
#define aegis128lx2_avx512_implementation  mc_aegis128lx2_avx512_implementation

#define aegis128lx4_aesni_implementation   mc_aegis128lx4_aesni_implementation
#define aegis128lx4_vaes_implementation    mc_aegis128lx4_vaes_implementation
#define aegis128lx4_avx2_implementation    mc_aegis128lx4_avx2_implementation
#define aegis128lx4_avx512_implementation  mc_aegis128lx4_avx512_implementation

#define aegis256x2_aesni_implementation    mc_aegis256x2_aesni_implementation
#define aegis256x2_vaes_implementation     mc_aegis256x2_vaes_implementation
#define aegis256x2_avx2_implementation     mc_aegis256x2_avx2_implementation
#define aegis256x2_avx512_implementation   mc_aegis256x2_avx512_implementation

#define aegis256x4_aesni_implementation    mc_aegis256x4_aesni_implementation
#define aegis256x4_vaes_implementation     mc_aegis256x4_vaes_implementation
#define aegis256x4_avx2_implementation     mc_aegis256x4_avx2_implementation
#define aegis256x4_avx512_implementation   mc_aegis256x4_avx512_implementation

/* --- Internal Tables (can conflict under -flto) --- */
#define _aes_lut                           mc_aegis_aes_lut
#define _aes_sbox                          mc_aegis_aes_sbox
#define _aes_isbox                         mc_aegis_aes_isbox
#define _aes_td                            mc_aegis_aes_td
#define _aes_te                            mc_aegis_aes_te

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions