diff --git a/LibGit2Sharp.Tests/GlobalSettingsFixture.cs b/LibGit2Sharp.Tests/GlobalSettingsFixture.cs index 17c11083d..925efc3d0 100644 --- a/LibGit2Sharp.Tests/GlobalSettingsFixture.cs +++ b/LibGit2Sharp.Tests/GlobalSettingsFixture.cs @@ -107,15 +107,15 @@ public void SetExtensions() public void OwnerValidation() { // Assert that owner validation is enabled by default - Assert.True(GlobalSettings.OwnerValidation); + Assert.True(GlobalSettings.GetOwnerValidation()); // Disable owner validation - GlobalSettings.OwnerValidation = false; - Assert.False(GlobalSettings.OwnerValidation); + GlobalSettings.SetOwnerValidation(false); + Assert.False(GlobalSettings.GetOwnerValidation()); // Enable it again - GlobalSettings.OwnerValidation = true; - Assert.True(GlobalSettings.OwnerValidation); + GlobalSettings.SetOwnerValidation(true); + Assert.True(GlobalSettings.GetOwnerValidation()); } } } diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index f6e6d9a31..cbb850b16 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -1,6 +1,8 @@ using System; using System.IO; +#if NET using System.Reflection; +#endif using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; @@ -743,13 +745,10 @@ internal static extern int git_libgit2_opts(int option, uint level, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string path); // git_libgit2_opts(GIT_OPT_ENABLE_*, int enabled) + // git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, int enabled) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern int git_libgit2_opts(int option, int enabled); - // git_libgit2_opts(GIT_OPT_GET_*, int *enabled) - [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] - internal static extern unsafe int git_libgit2_opts(int option, int* enabled); - // git_libgit2_opts(GIT_OPT_SET_USER_AGENT, const char *path) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern int git_libgit2_opts(int option, @@ -766,6 +765,10 @@ internal static extern int git_libgit2_opts(int option, // git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, git_strarray *out) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] internal static extern int git_libgit2_opts(int option, out GitStrArray extensions); + + // git_libgit2_opts(GIT_OPT_GET_OWNER_VALIDATION, int *enabled) + [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] + internal static extern unsafe int git_libgit2_opts(int option, int* enabled); #endregion #region git_libgit2_opts_osxarm64 @@ -783,13 +786,10 @@ internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, In [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string path); // git_libgit2_opts(GIT_OPT_ENABLE_*, int enabled) + // git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, int enabled) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")] internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, int enabled); - // git_libgit2_opts(GIT_OPT_GET_*, int enabled) - [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")] - internal static extern unsafe int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, int* enabled); - // git_libgit2_opts(GIT_OPT_SET_USER_AGENT, const char *path) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")] internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, @@ -806,6 +806,10 @@ internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, In // git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, git_strarray *out) [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")] internal static extern int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, out GitStrArray extensions); + + // git_libgit2_opts(GIT_OPT_GET_OWNER_VALIDATION, int *enabled) + [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl, EntryPoint = "git_libgit2_opts")] + internal static extern unsafe int git_libgit2_opts_osxarm64(int option, IntPtr nop2, IntPtr nop3, IntPtr nop4, IntPtr nop5, IntPtr nop6, IntPtr nop7, IntPtr nop8, int* enabled); #endregion [DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)] diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 08555eb02..83d35e22c 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -3577,13 +3577,20 @@ public static string[] git_libgit2_opts_get_extensions() /// public static unsafe bool git_libgit2_opts_get_owner_validation() { - // libgit2 expects non-zero value for true - int res, enabled; + int res; + int enabled; + if (isOSXArm64) + { res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.GetOwnerValidation, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, &enabled); + } else + { res = NativeMethods.git_libgit2_opts((int)LibGit2Option.GetOwnerValidation, &enabled); + } + Ensure.ZeroResult(res); + return enabled != 0; } @@ -3593,15 +3600,19 @@ public static unsafe bool git_libgit2_opts_get_owner_validation() /// true to enable owner validation, false otherwise public static void git_libgit2_opts_set_owner_validation(bool enabled) { - // libgit2 expects non-zero value for true int res; + if (isOSXArm64) + { res = NativeMethods.git_libgit2_opts_osxarm64((int)LibGit2Option.SetOwnerValidation, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, enabled ? 1 : 0); + } else + { res = NativeMethods.git_libgit2_opts((int)LibGit2Option.SetOwnerValidation, enabled ? 1 : 0); + } + Ensure.ZeroResult(res); } - #endregion #region git_worktree_ diff --git a/LibGit2Sharp/GlobalSettings.cs b/LibGit2Sharp/GlobalSettings.cs index e11410e28..9807155e7 100644 --- a/LibGit2Sharp/GlobalSettings.cs +++ b/LibGit2Sharp/GlobalSettings.cs @@ -204,19 +204,6 @@ public static string NativeLibraryPath } } - /// - /// Controls the status of repository directory owner validation. - /// - /// - /// By default, repository directories must be owned by the current user to be opened. This can be disabled by setting this property to false. - /// Note that disabling this can lead to security vulnerabilities (see CVE-2022-24765). - /// - public static bool OwnerValidation - { - get => Proxy.git_libgit2_opts_get_owner_validation(); - set => Proxy.git_libgit2_opts_set_owner_validation(value); - } - internal static string GetAndLockNativeLibraryPath() { nativeLibraryPathLocked = true; @@ -430,5 +417,26 @@ public static string GetUserAgent() { return Proxy.git_libgit2_opts_get_user_agent(); } + + /// + /// Gets the owner validation setting for repository directories. + /// + /// + public static bool GetOwnerValidation() + { + return Proxy.git_libgit2_opts_get_owner_validation(); + } + + /// + /// Sets whether repository directories should be owned by the current user. The default is to validate ownership. + /// + /// + /// Disabling owner validation can lead to security vulnerabilities (see CVE-2022-24765). + /// + /// true to enable owner validation; otherwise, false. + public static void SetOwnerValidation(bool enabled) + { + Proxy.git_libgit2_opts_set_owner_validation(enabled); + } } }