Skip to content

Commit 4bfa9e8

Browse files
rmarinhoCopilot
andauthored
Fix native resource leaks in Keychain (#184)
- GetAllSigningIdentities: CFRelease the CFDataRef returned by SecCertificateCopyData (Copy semantics = +1 retain count). - GetAllSigningCertificates: Same CFDataRef leak fix. - FindInternetUserNameAndPassword: Free passwordData with SecKeychainItemFreeContent and release the item ref. - FindInternetPassword(string,...): Same leak fix. - FindInternetPassword(Uri): Free passwordData and align cleanup. All three FindInternet* methods now use try/finally to guarantee native resources are freed even if GetUsernameFromKeychainItemRef or marshaling throws. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 3b81c64 commit 4bfa9e8

1 file changed

Lines changed: 26 additions & 11 deletions

File tree

Xamarin.MacDev/Keychain.cs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ public IList<AppleCodeSigningIdentity> GetAllSigningIdentities ()
459459
if (SecIdentityCopyCertificate (itemRef, out certRef) == OSStatus.Ok) {
460460
var data = SecCertificateCopyData (certRef);
461461
var rawData = CFDataGetBytes (data);
462+
CFRelease (data);
462463

463464
if (rawData != null) {
464465
try {
@@ -520,6 +521,7 @@ public IList<X509Certificate2> GetAllSigningCertificates ()
520521
if (SecIdentityCopyCertificate (itemRef, out certRef) == OSStatus.Ok) {
521522
var data = SecCertificateCopyData (certRef);
522523
var rawData = CFDataGetBytes (data);
524+
CFRelease (data);
523525

524526
if (rawData != null) {
525527
try {
@@ -943,9 +945,14 @@ public unsafe Tuple<string, string> FindInternetUserNameAndPassword (Uri uri)
943945
if (result != OSStatus.Ok)
944946
return null;
945947

946-
var username = GetUsernameFromKeychainItemRef (item);
947-
948-
return Tuple.Create (username, Marshal.PtrToStringAuto (passwordData, (int) passwordLength));
948+
try {
949+
var username = GetUsernameFromKeychainItemRef (item);
950+
var password = Marshal.PtrToStringAuto (passwordData, (int) passwordLength);
951+
return Tuple.Create (username, password);
952+
} finally {
953+
SecKeychainItemFreeContent (IntPtr.Zero, passwordData);
954+
CFRelease (item);
955+
}
949956
}
950957

951958
public unsafe Tuple<string, string> FindInternetPassword (string serverName = "", string securityDomain = "", string accountName = "", string path = "", ushort port = 0)
@@ -969,9 +976,14 @@ public unsafe Tuple<string, string> FindInternetPassword (string serverName = ""
969976
if (result != OSStatus.Ok)
970977
return null;
971978

972-
var username = GetUsernameFromKeychainItemRef (item);
973-
974-
return Tuple.Create (username, Marshal.PtrToStringAuto (passwordData, (int) passwordLength));
979+
try {
980+
var username = GetUsernameFromKeychainItemRef (item);
981+
var password = Marshal.PtrToStringAuto (passwordData, (int) passwordLength);
982+
return Tuple.Create (username, password);
983+
} finally {
984+
SecKeychainItemFreeContent (IntPtr.Zero, passwordData);
985+
CFRelease (item);
986+
}
975987
}
976988

977989
public string FindInternetPassword (Uri uri)
@@ -996,12 +1008,15 @@ public string FindInternetPassword (Uri uri)
9961008
(uint) user.Length, user, (uint) path.Length, path, (ushort) uri.Port,
9971009
0, auth, out passwordLength, out passwordData, ref item);
9981010

999-
CFRelease (item);
1000-
1001-
if (result != OSStatus.Ok)
1002-
return null;
1011+
try {
1012+
if (result != OSStatus.Ok)
1013+
return null;
10031014

1004-
return Marshal.PtrToStringAuto (passwordData, (int) passwordLength);
1015+
return Marshal.PtrToStringAuto (passwordData, (int) passwordLength);
1016+
} finally {
1017+
SecKeychainItemFreeContent (IntPtr.Zero, passwordData);
1018+
CFRelease (item);
1019+
}
10051020
}
10061021
}
10071022

0 commit comments

Comments
 (0)