Skip to content

Commit 1ae1897

Browse files
Fixing bugs found during Code Review.
1 parent fb5f220 commit 1ae1897

File tree

4 files changed

+22
-20
lines changed

4 files changed

+22
-20
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@
1313
/.vs/ql/v15/Browse.VC.db
1414
/.vs/ProjectSettings.json
1515

16+
/.vs/ql_ICryptoTransform/v15/Browse.VC.opendb
17+
/.vs/ql_ICryptoTransform/v15/Browse.VC.db
18+
/.vs/ql_ICryptoTransform/v15/.suo

csharp/ql/src/Likely Bugs/ThreadUnSafeICryptoTransformBad.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
internal class TokenCacheThreadUnsafeICryptoTransformDemoFixed
1+
internal class TokenCacheThreadUnsafeICryptoTransformDemo
22
{
3-
// We are replacing the static SHA256 field with an instance one
4-
//
5-
//private static SHA256 _sha = SHA256.Create();
6-
private SHA256 _sha = SHA256.Create();
3+
private static SHA256 _sha = SHA256.Create();
74

85
public string ComputeHash(string data)
96
{
@@ -21,8 +18,8 @@ static void Main(string[] args)
2118

2219
Action<object> action = (object obj) =>
2320
{
24-
var safeObj = new TokenCacheThreadUnsafeICryptoTransformDemoFixed();
25-
if (safeObj.ComputeHash((string)obj) != "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=")
21+
var unsafeObj = new TokenCacheThreadUnsafeICryptoTransformDemo();
22+
if (unsafeObj.ComputeHash((string)obj) != "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=")
2623
{
2724
Console.WriteLine("**** We got incorrect Results!!! ****");
2825
}

csharp/ql/src/Likely Bugs/ThreadUnSafeICryptoTransformGood.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
internal class TokenCacheThreadUnsafeICryptoTransformDemo
1+
internal class TokenCacheThreadUnsafeICryptoTransformDemoFixed
22
{
3-
private static SHA256 _sha = SHA256.Create();
3+
// We are replacing the static SHA256 field with an instance one
4+
//
5+
//private static SHA256 _sha = SHA256.Create();
6+
private SHA256 _sha = SHA256.Create();
47

58
public string ComputeHash(string data)
69
{
@@ -18,8 +21,8 @@ static void Main(string[] args)
1821

1922
Action<object> action = (object obj) =>
2023
{
21-
var unsafeObj = new TokenCacheThreadUnsafeICryptoTransformDemo();
22-
if (unsafeObj.ComputeHash((string)obj) != "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=")
24+
var safeObj = new TokenCacheThreadUnsafeICryptoTransformDemoFixed();
25+
if (safeObj.ComputeHash((string)obj) != "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=")
2326
{
2427
Console.WriteLine("**** We got incorrect Results!!! ****");
2528
}

csharp/ql/src/Likely Bugs/ThreadUnsafeICryptoTransform.qhelp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,22 @@
44
<qhelp>
55
<overview>
66
<p>Classes that implement <code>System.Security.Cryptography.ICryptoTransform</code> are not thread safe.</p>
7-
<p>The root cause of the problem is because of the way these class are implemented using Microsoft CAPI/CNG patterns.</p>
8-
<p>For example, a hash class implementing this interface, typically there would be an instance-specific hash object (i.e. using <code>BCryptCreateHash</code> function), which can be called multiple times to add data to the hash (i.e. <code>BCryptHashData</code>), and finally calling the function that would finish the hash & get back the data (i.e. <code>BCryptFinishHash</code>).</p>
9-
<p>The implementation would potentially allow the same hash object to be called with data from multiple threads before calling the finish function, thus leading to potentially incorrect results.</p>
10-
<p>Because of this pattern, you can expect that, if you have multiple threads hashing <code>"abc"</code> on a static hash object, you may occasionally obtain the results (incorrectly) for hashing <code>"abcabc"</code>, or face other unexpected behavior.</p>
11-
<p>It is very unlikely somebody outside Microsoft would write a class that implements <code>ICryptoTransform</code>, and even if they do, it is likely that they will follow the same common pattern than the existing classes implementing this interface.</p>
7+
<p>This problem is caused by the way these classes are implemented using Microsoft CAPI/CNG patterns.</p>
8+
<p>For example, when a hash class implements this interface, there would typically be an instance-specific hash object created (for example using <code>BCryptCreateHash</code> function). This object can be called multiple times to add data to the hash (for example <code>BCryptHashData</code>). Finally, a function is called that finishes the hash and returns the data (for example <code>BCryptFinishHash</code>).</p>
9+
<p>Allowing the same hash object to be called with data from multiple threads before calling the finish function could potentially lead to incorrect results.</p>
10+
<p>For example, if you have multiple threads hashing <code>"abc"</code> on a static hash object, you may occasionally obtain the results (incorrectly) for hashing <code>"abcabc"</code>, or face other unexpected behavior.</p>
11+
<p>It is very unlikely somebody outside Microsoft would write a class that implements <code>ICryptoTransform</code>, and even if they do, it is likely that they will follow the same common pattern as the existing classes implementing this interface.</p>
1212
<p>Any object that implements <code>System.Security.Cryptography.ICryptoTransform</code> should not be used in concurrent threads as the instance members of such object are also not thread safe.</p>
13-
<p>Potential problems may not be evident at first, but can range from explicit errors such as exceptions, to incorrect results when sharing an instance of such object in multiple threads.</p>
13+
<p>Potential problems may not be evident at first, but can range from explicit errors such as exceptions, to incorrect results when sharing an instance of such an object in multiple threads.</p>
1414

1515
</overview>
1616
<recommendation>
17-
<p>Verify that the object is not being shared across threads.</p>
18-
<p>If it is shared accross instances. Consider changing the code to use a non-static object of type <code>System.Security.Cryptography.ICryptoTransform</code> instead.</p>
17+
<p>If the object is shared across instances, you should consider changing the code to use a non-static object of type <code>System.Security.Cryptography.ICryptoTransform</code> instead.</p>
1918
<p>As an alternative, you could also look into using <code>ThreadStatic</code> attribute, but make sure you read the initialization remarks on the documentation.</p>
2019

2120
</recommendation>
2221
<example>
23-
<p>This example demonstrates the dangers of using a static <code>System.Security.Cryptography.ICryptoTransform</code> in such a way that the results may be incorrect.</p>
22+
<p>This example demonstrates the dangers of using a static <code>System.Security.Cryptography.ICryptoTransform</code> in a way that generates incorrect results.</p>
2423
<sample src="ThreadUnSafeICryptoTransformBad.cs" />
2524

2625
<p>A simple fix is to change the <code>_sha</code> field from being a static member to an instance one by removing the <code>static</code> keyword.</p>

0 commit comments

Comments
 (0)