git2-rs icon indicating copy to clipboard operation
git2-rs copied to clipboard

Panic when authenticating with ssh key

Open tomasalagoa opened this issue 2 years ago • 2 comments

uname -a output: Linux HAL-9K 5.16.14-1-MANJARO #1 SMP PREEMPT Fri Mar 11 14:12:18 UTC 2022 x86_64 GNU/Linux

I am trying to push to a repository with an existing private key, with no passphrase. However, when pushing I get a segmentation fault.

remote_callbacks.credentials(|_url, username_from_url, _allowed_types| {
                    git2::Cred::ssh_key(
                        username_from_url.unwrap(),
                        None,
                        std::path::Path::new(&format!("{}/.ssh/github", env::var("HOME").unwrap())),
                        None,
                    )
                });

The full source code can be found here (nevermind the hard-coded paths, the project is still a WIP)

Running valgrind on the target binary produces the following output:

==52788== Conditional jump or move depends on uninitialised value(s)
==52788==    at 0x4926FA0: ??? (in /usr/lib/libgit2.so.1.4.0)
==52788==    by 0x492D0AC: git_remote_push (in /usr/lib/libgit2.so.1.4.0)
==52788==    by 0x4BC9F4: git2::remote::Remote::push (remote.rs:329)
==52788==    by 0x4B8F00: <nabu::git::WatchedRepository as nabu::git::Repository>::push (git.rs:146)
==52788==    by 0x20ECC1: nabu::watch::Watch<R>::run (watch.rs:203)
==52788==    by 0x20C20B: nabu::watch::WatchArgs::run (watch.rs:87)
==52788==    by 0x207878: nabu::main (main.rs:52)
==52788==    by 0x216A3A: core::ops::function::FnOnce::call_once (function.rs:227)
==52788==    by 0x22141D: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:123)
==52788==    by 0x21AA60: std::rt::lang_start::{{closure}} (rt.rs:145)
==52788==    by 0x809E8F: std::rt::lang_start_internal (function.rs:259)
==52788==    by 0x21AA2F: std::rt::lang_start (rt.rs:144)
==52788== 
==52788== Invalid read of size 8
==52788==    at 0x4926FC0: ??? (in /usr/lib/libgit2.so.1.4.0)
==52788==    by 0x492D0AC: git_remote_push (in /usr/lib/libgit2.so.1.4.0)
==52788==    by 0x4BC9F4: git2::remote::Remote::push (remote.rs:329)
==52788==    by 0x4B8F00: <nabu::git::WatchedRepository as nabu::git::Repository>::push (git.rs:146)
==52788==    by 0x20ECC1: nabu::watch::Watch<R>::run (watch.rs:203)
==52788==    by 0x20C20B: nabu::watch::WatchArgs::run (watch.rs:87)
==52788==    by 0x207878: nabu::main (main.rs:52)
==52788==    by 0x216A3A: core::ops::function::FnOnce::call_once (function.rs:227)
==52788==    by 0x22141D: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:123)
==52788==    by 0x21AA60: std::rt::lang_start::{{closure}} (rt.rs:145)
==52788==    by 0x809E8F: std::rt::lang_start_internal (function.rs:259)
==52788==    by 0x21AA2F: std::rt::lang_start (rt.rs:144)
==52788==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==52788== 
==52788== 
==52788== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==52788==  Access not within mapped region at address 0x0
==52788==    at 0x4926FC0: ??? (in /usr/lib/libgit2.so.1.4.0)
==52788==    by 0x492D0AC: git_remote_push (in /usr/lib/libgit2.so.1.4.0)
==52788==    by 0x4BC9F4: git2::remote::Remote::push (remote.rs:329)
==52788==    by 0x4B8F00: <nabu::git::WatchedRepository as nabu::git::Repository>::push (git.rs:146)
==52788==    by 0x20ECC1: nabu::watch::Watch<R>::run (watch.rs:203)
==52788==    by 0x20C20B: nabu::watch::WatchArgs::run (watch.rs:87)
==52788==    by 0x207878: nabu::main (main.rs:52)
==52788==    by 0x216A3A: core::ops::function::FnOnce::call_once (function.rs:227)
==52788==    by 0x22141D: std::sys_common::backtrace::__rust_begin_short_backtrace (backtrace.rs:123)
==52788==    by 0x21AA60: std::rt::lang_start::{{closure}} (rt.rs:145)
==52788==    by 0x809E8F: std::rt::lang_start_internal (function.rs:259)
==52788==    by 0x21AA2F: std::rt::lang_start (rt.rs:144)
==52788==  If you believe this happened as a result of a stack
==52788==  overflow in your program's main thread (unlikely but
==52788==  possible), you can try to increase the size of the
==52788==  main thread stack using the --main-stacksize= flag.
==52788==  The main thread stack size used in this run was 8388608.
==52788== 
==52788== HEAP SUMMARY:
==52788==     in use at exit: 771,648 bytes in 14,221 blocks
==52788==   total heap usage: 32,828 allocs, 18,607 frees, 3,069,508 bytes allocated
==52788== 
==52788== LEAK SUMMARY:
==52788==    definitely lost: 0 bytes in 0 blocks
==52788==    indirectly lost: 0 bytes in 0 blocks
==52788==      possibly lost: 1,324 bytes in 7 blocks
==52788==    still reachable: 770,324 bytes in 14,214 blocks
==52788==         suppressed: 0 bytes in 0 blocks
==52788== Rerun with --leak-check=full to see details of leaked memory
==52788== 
==52788== Use --track-origins=yes to see where uninitialised values come from
==52788== For lists of detected and suppressed errors, rerun with: -s
==52788== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)

tomasalagoa avatar Mar 17 '22 19:03 tomasalagoa

Maybe this is related to https://github.com/rust-lang/git2-rs/issues/813?

jmg-duarte avatar Mar 17 '22 22:03 jmg-duarte

I made a minimal reproducible program to test this, the only requirement is a repository ready to push:

use std::{env::current_dir, path::PathBuf};

use git2::PushOptions;

fn push() {
    let repo = git2::Repository::open(current_dir().unwrap()).unwrap();

    // TODO: allow remote to be configurable
    let mut remote = repo.find_remote("origin").unwrap();

    let head = repo.head().unwrap();
    let refspecs: &[&str] = &[head.name().unwrap()];

    let mut remote_callbacks = git2::RemoteCallbacks::new();

    remote_callbacks.credentials(move |_url, username_from_url, _allowed_types| {
        git2::Cred::ssh_key(
            username_from_url.unwrap(),
            Some(&PathBuf::from("/home/tomas/.ssh/github.pub")),
            &PathBuf::from("/home/tomas/.ssh/github"),
            Some(""),
        )
    });

    let mut push_options = PushOptions::new();
    push_options.remote_callbacks(remote_callbacks);

    remote.push(refspecs, Some(&mut push_options)).unwrap();
}

fn main() {
    push();
}

tomasalagoa avatar Mar 17 '22 22:03 tomasalagoa