Skip to content

AccessViolationException in Proxy.git_remote_push #1217

Closed
@golsby

Description

@golsby

Summary
GitPushOptions (CS) signature mismatch with git_push_options (C) causes uninitialized memory and access violation when calling git_remote_push in libgit2 when credentials are passed for accessing a private repo. The custom_headers member of git_push_options points to random garbage after the call is marshalled because the corresponding member is missing from GitPushOptions.

As a side note, GitHub Desktop cannot push to our private repo, but it doesn't report anything useful when it fails. I imagine this is the cause.

To Reproduce:
Using commit 9d17afe (Oct 23) I'm trying to push using the following code. I'm pushing to a private repo on GitHub using username/personal access token pair.

      if (string.IsNullOrWhiteSpace(Branch))
        Branch = "master";

      using (var repo = new Repository(WorkingTree))
      {
        Log.LogMessage("Pushing branch '{0}' from '{1}'", Branch, WorkingTree);
        LibGit2Sharp.PushOptions options = new LibGit2Sharp.PushOptions();
        options.CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials { Username = Username, Password = Password };
        var branch = repo.Branches[Branch];
        lock (m_lock)
        {
          repo.Network.Push(branch, options);
        }
      }
      return true;

This results in a 'System.AccessViolationException'.

Details
Debugging into this, I see that git_remote_push on line 2450 of remote.c takes git_push_options as a parameter. From remote.h:

/**
 * Controls the behavior of a git_push object.
 */
typedef struct {
    unsigned int version;

    /**
     * If the transport being used to push to the remote requires the creation
     * of a pack file, this controls the number of worker threads used by
     * the packbuilder when creating that pack file to be sent to the remote.
     *
     * If set to 0, the packbuilder will auto-detect the number of threads
     * to create. The default value is 1.
     */
    unsigned int pb_parallelism;

    /**
     * Callbacks to use for this push operation
     */
    git_remote_callbacks callbacks;

    /**
     * Extra headers for this push operation
     */
    git_strarray custom_headers;
} git_push_options;

The corresponding C# type is GitPushOptions
defined as

namespace LibGit2Sharp.Core
{
    [StructLayout(LayoutKind.Sequential)]
    internal class GitPushOptions
    {
        public int Version = 1;
        public int PackbuilderDegreeOfParallelism;
        public GitRemoteCallbacks RemoteCallbacks;
    }
}

Notice that GitPushOptions is missing the custom_headers member.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions