SOCI / soci

Official repository of the SOCI - The C++ Database Access Library
http://soci.sourceforge.net/
Boost Software License 1.0
1.41k stars 477 forks source link

AddressSanitizer: soci + sqlite3 fails #1074

Closed tcanabrava closed 1 year ago

tcanabrava commented 1 year ago
==3503==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fbec6d150b0 at pc 0x7fbed6238aa3 bp 0x7fffcec52420 sp 0x7fffcec52418
READ of size 4 at 0x7fbec6d150b0 thread T0
    #0 0x7fbed6238aa2 in soci::sqlite3_standard_use_type_backend::pre_use(soci::indicator const*) /builds/sdk/codevis/thirdparty/soci/src/backends/sqlite3/standard-use-type.cpp:122
    #1 0x7fbed61e9458 in soci::details::standard_use_type::pre_use() /builds/sdk/codevis/thirdparty/soci/src/core/use-type.cpp:128
    #2 0x7fbed61ddaee in soci::details::statement_impl::pre_use() /builds/sdk/codevis/thirdparty/soci/src/core/statement.cpp:576
    #3 0x7fbed61dbc1f in soci::details::statement_impl::execute(bool) /builds/sdk/codevis/thirdparty/soci/src/core/statement.cpp:279
    #4 0x7fbed615cf38 in soci::statement::execute(bool) /builds/sdk/codevis/thirdparty/soci/include/soci/statement.h:216
    #5 0x7fbed615cc7f in soci::details::ref_counted_statement::final_action() /builds/sdk/codevis/thirdparty/soci/src/core/ref-counted-statement.cpp:54
    #6 0x7fbed6156c5f in soci::details::ref_counted_statement_base::dec_ref() /builds/sdk/codevis/thirdparty/soci/include/soci/ref-counted-statement.h:45
    #7 0x7fbed6154753 in soci::details::once_temp_type::~once_temp_type() /builds/sdk/codevis/thirdparty/soci/src/core/once-temp-type.cpp:40
    #8 0x7fbed631b152 in exportFile /builds/sdk/codevis/lvtmdb/ct_lvtmdb_soci_writer.cpp:287
    #9 0x7fbed633146f in Codethink::lvtmdb::SociWriter::writeFrom(Codethink::lvtmdb::ObjectStore const&) /builds/sdk/codevis/lvtmdb/ct_lvtmdb_soci_writer.cpp:744

The code in question:

void exportFile(FileObject *file, soci::session& db)
{
    auto lock = file->readOnlyLock();
    (void) lock;

    if (query_id_from_qual_name(db, "source_file", file->qualifiedName()).has_value()) {
        return;
    }

    auto [pkg_id, pkg_ind] = get_or_add_thing(file->package(), db, "source_package", exportPackage);
    auto [component_id, component_ind] = get_or_add_thing(file->component(), db, "source_component", exportComponent);

    db << "insert into source_file(version, package_id, component_id, name, qualified_name, is_header, hash)"
          "values(0, :pkg_id, :comp_id, :name, :qual_name, :is_header, :hash)",
        soci::use(pkg_id, pkg_ind), soci::use(component_id, component_ind), soci::use(file->name()),
        soci::use(file->qualifiedName()), soci::use(file->isHeader() ? 1 : 0), soci::use(file->hash());
}

I don't see an obvious API usage mistake, but I believe Asan is probably right.

vadz commented 1 year ago

This is same problem as is fixed by #1071: you can't pass constants such as 1 or 0 to use() right now, you have to use an r-value reference.