Skip to content

Unsound api: row.next() invalidation not covered by lifetime and may* cause use-after-free #2257

Description

@CharaVerKys

synopsis:

charaverk | ~/repos/libsql_execute/src ~$ cat main.rs 
fn main() {
    let runtime = tokio::runtime::Runtime::new().unwrap();
    runtime.block_on(async{
        let db = libsql::Builder::new_local("/tmp/test.db").build().await.unwrap();
        let conn = db.connect().unwrap();
/*
        conn.execute("CREATE TABLE IF NOT EXISTS test_table(id INTEGER PRIMARY KEY, data TEXT)", ()).await.unwrap();
        let _res = conn.execute(
            "INSERT INTO test_table(id, data) VALUES(0, ?1);
            ", [ "some str content" ]).await;
*/
        let mut res = conn.query(
            "SELECT data FROM test_table WHERE id == ?1;
            ", [ 0 ]).await.unwrap();
        let row = res.next().await.unwrap().unwrap();
        let str_ref = row.get_str(0).unwrap();
        let erm = res.next().await;
        //* unsound here, quickly debugged what cause, but still...
        let str_ = str_ref.to_owned(); //? invalidation that can lead to 'use after free' 
                                       //?   or just logical error?
        println!("{erm:?} {str_}");
    });
}

as in example, when from current row user get_str, it return non owning &str, and next call of rows.next() will cause invalidation of whatever was under reference str_ref

using previous row after call to next is already invalid, but it will not cause memory issues
using &str to previous row, probably not cause memory issues now:

@sivukhin says:

for local client libsql/sqlite reuse memory for the columns between next() calls which makes this bug possible...
I wouldn't rely on the reuse semantic too much. SQLite/libsql can free this memory after next() call too I think

so, seems like currently it can only lead to logical error, but would be better to somehow cover it, tho, i not know how to do so without allocating for each str

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions