You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/code-quality/c26441.md
+7-6Lines changed: 7 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,16 +9,17 @@ helpviewer_keywords: ["C26441"]
9
9
10
10
> Guard objects must be named (cp.44)
11
11
12
-
**C++ Core Guidelines**:
13
-
[CP.44](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#cp44-remember-to-name-your-lock_guards-and-unique_locks): Remember to name your lock_guards and unique_locks
12
+
## C++ Core Guidelines
13
+
14
+
[CP.44](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#cp44-remember-to-name-your-lock_guards-and-unique_locks): Remember to name your `lock_guard`s and `unique_lock`s
14
15
15
16
## Remarks
16
17
17
-
The standard library provides locks to help control concurrent access to resources during their lifetime. Attempting to declare a lock object without a name, creates a temporary object that is immediately destructed rather than living to the end of the enclosing scope. So, failing to assign a lock object to a variable is a mistake that effectively disables the locking mechanism (because temporary variables are transient). This rule tries to catch simple cases of such unintended behavior.
18
+
The standard library provides locks to help control concurrent access to resources during their lifetime. When you declare a lock object without a name, the compiler creates a temporary object that's immediately destructed rather than one that lives to the end of the enclosing scope. So, failure to assign a lock object to a variable is a mistake that effectively disables the locking mechanism (because temporary variables are transient). This rule tries to catch simple cases of such unintended behavior.
18
19
19
-
This diagnostic will only fire for the standard lock types`std::scoped_lock`, `std::unique_lock`, and `std::lock_guard`. Other unnamed RAII types are covered by [C26444](c26444.md).
20
+
This diagnostic only analyzes the standard lock types `std::scoped_lock`, `std::unique_lock`, and `std::lock_guard`. Other unnamed RAII types are covered by [C26444](c26444.md).
20
21
21
-
Only simple calls to constructors are analyzed. More complex initializer expressions may lead to inaccurate results, but it's an unusual scenario. Locks passed as arguments to function calls or returned as results of function calls are ignored. To provide similar protection for types returned by a function call, annotate with `[[nodiscard]]`. Locks created as temporaries but assigned to named references to extend their lifetime are ignored.
22
+
Only simple calls to constructors are analyzed. More complex initializer expressions may lead to inaccurate results, but it's an unusual scenario. Locks passed as arguments to function calls or returned as results of function calls are ignored. To provide similar protection for types returned by a function call, annotate them with `[[nodiscard]]`. Locks created as temporaries but assigned to named references to extend their lifetime are ignored.
`_Use_decl_annotations_` tells the compiler to use the annotations from an earlier declaration of the function. If no earlier declaration can be found, or if the current declaration makes changes to the annotations, then this warning is emitted. `_Use_decl_annotations_` also allows removing all other annotations from the definition and will use the declaration annotations for analysis of the function.
14
+
`_Use_decl_annotations_` tells the compiler to use the annotations from an earlier declaration of the function. If no earlier declaration can be found, or if the current declaration makes changes to the annotations, then this warning is emitted. `_Use_decl_annotations_` also lets you remove all other annotations from the definition, and uses the declaration annotations for analysis of the function.
15
15
16
-
This diagnostic is frequently a side effect of refactoring or fixing other warnings by adjusting the annotations on a function. If this is the case then to fix the issue, the 'correct' set of annotations needs to replace the annotations at the other locations. To determine the correct set of annotations, look at the behavior in the function definition. In most cases this behavior is intended and should be reflected in the annotations to the function. Refer to the guide on [Using SAL Annotations to reduce code defects](using-sal-annotations-to-reduce-c-cpp-code-defects.md) for more information on SAL.
16
+
This diagnostic is frequently a side effect of refactoring or fixing other warnings by adjusting the annotations on a function. To fix the issue, use the same annotations at the other locations. To determine the correct set of annotations, look at the behavior in the function definition. In most cases, this behavior is intentional and should be reflected in the annotations to the function. For more information on SAL annotations, see [Using SAL Annotations to reduce code defects](using-sal-annotations-to-reduce-c-cpp-code-defects.md).
17
17
18
-
It is important for the annotations to match between the declarations and the definition of a function. When analyzing the call site of the function the declaration annotations are used, so when the declaration and definition do not match it leads to incorrect results from the static analysis tools. When fixing this warning, it is common for it to have cascading effects as the tool reanalyzes the source with updated information.
18
+
It's important for the annotations to match between the declarations and the definition of a function. When the analysis tools analyze the call site of the function, the declaration annotations are used. If the declaration and definition don't match, the static analysis tools may produce incorrect results. When you fix this warning, it's common for your changes to have cascading effects as the tool reanalyzes the source with updated information.
19
19
20
-
If this diagnostic is a result of no previous declaration being found in the translation unit then there is most likely a missing `#include`. If the header file is intentionally not included then to resolve this issue you can verify the the annotations in the declaration and definition match and remove `_Use_decl_annotations_`. Be careful when doing this as the two sets of annotations may get out of sync in the future.
20
+
If this diagnostic occurs because no previous declaration was found in the translation unit, the most likely cause is a missing `#include` directive. To resolve this issue when the header file is intentionally not included, verify that the annotations in the declaration and definition match, and remove the `_Use_decl_annotations_` annotation. Be careful when you don't include a header file, as the two sets of annotations may get out of sync in the future.
21
21
22
-
Code analysis name: BAD_USEHEADER
22
+
Code analysis name: `BAD_USEHEADER`
23
23
24
24
## Examples
25
25
@@ -41,9 +41,9 @@ void example_func(_Out_writes_z_(n) char* buffer, int n)
41
41
}
42
42
```
43
43
44
-
This issue can be fixed by either changing the annotation so they match at all locations, or by removing all annotations except `_Use_decl_annotations_` from the function definition after verifying the declaration annotations are correct. In this simple example, `_Out_writes_z_` appears to be correct so we'll move that annotation to the function declaration in the header file. We will also remove all other annotations from the definition to simplify future maintenance although this is optional.
44
+
To fix this issue, either change the annotations so they match at all locations, or after verifying the declaration annotations are correct, remove all annotations except `_Use_decl_annotations_` from the function definition. In this example, `_Out_writes_z_` appears to be correct, so we move that annotation to the function declaration in the header file. You can also remove all other annotations from the definition to simplify future maintenance, although this step is optional.
45
45
46
-
In real world code it is usually not as clear which annotation is correct, consult with the documentation on [using SAL Annotations to reduce code defects](using-sal-annotations-to-reduce-c-cpp-code-defects.md) for additional guidance.
46
+
In real world code, it's not usually as clear which annotation is correct. For more information and guidance, see [using SAL Annotations to reduce code defects](using-sal-annotations-to-reduce-c-cpp-code-defects.md).
Copy file name to clipboardExpand all lines: docs/code-quality/c6029.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,13 +13,13 @@ Possible buffer overrun in function called due to an unchecked buffer length/siz
13
13
14
14
## Remarks
15
15
16
-
This warning indicates that a function taking a buffer and a size is being passed an unchecked size. The data read-in from some external source hasn't been verified to see whether it's smaller than the buffer size. An attacker might intentionally specify a much larger than expected value for the size, which will lead to a buffer overrun. Generally, whenever you read data from an untrusted external source, make sure to verify it for validity. It's appropriate to verify the size to make sure it's in the expected range.
16
+
This warning indicates a function that takes a buffer and a size is passed an unchecked size. The data read-in from some external source hasn't been verified to see whether it's smaller than the buffer size. An attacker might intentionally specify a far larger than expected value for the size, which can lead to a buffer overrun. Generally, whenever you read data from an untrusted external source, make sure to verify it for validity. It's appropriate to verify the size to make sure it's in the expected range.
17
17
18
18
Code analysis name: `USING_TAINTED_DATA`
19
19
20
20
## Example
21
21
22
-
The following code generates this warning by calling the annotated function `std::fread` two times. The first call is used to determine the length of the data to read in later calls. After the first call`dataSize`has been marked by the analysis as coming from an untrusted source. Therefore, passing the untrusted value to the second `std::fread` call generates this warning. A malicious actor would be able to modify the file and cause the call to `std::fread` to overflow the `buffer` array. In read world code there should also be error recovery based on the return value of `std::fread`, this is purposely left out of these examples for simplicity.
22
+
The following code generates this warning by calling the annotated function `std::fread` two times. The first call is used to determine the length of the data to read in later calls. After the first call, analysis marks `dataSize` as coming from an untrusted source. Therefore, passing the untrusted value to the second `std::fread` call generates this warning. A malicious actor would be able to modify the file and cause the call to `std::fread` to overflow the `buffer` array. In real world code, you should also handle error recovery based on the return value of `std::fread`. For simplicity, error recovery is intentionally left out of these examples.
23
23
24
24
```cpp
25
25
voidprocessData(FILE* file)
@@ -35,7 +35,7 @@ void processData(FILE* file)
35
35
}
36
36
```
37
37
38
-
The fix for the issue depends on the nature of the data and the behavior of the annotated function that is triggering the diagnostic. You may need to consult the documentation for that function for more information. A straightforward fix is to check the size before the second call to `std:fread`. In the next example we throw an exception to terminate the function, although most code would instead have an error recovery strategy that is specific to the scenario.
38
+
The fix for the issue depends on the nature of the data and the behavior of the annotated function that is triggering the diagnostic. For more information, see the documentation for that function. A straightforward fix is to check the size before the second call to `std:fread`. In the next example, we throw an exception to terminate the function. Most real-world code would instead have an error recovery strategy that is specific to the scenario.
39
39
40
40
```cpp
41
41
void processData(FILE* file)
@@ -55,7 +55,7 @@ void processData(FILE* file)
55
55
}
56
56
```
57
57
58
-
In the case of `std:fread` and similar functions, the data may need to be read even if it is large. This can be done by allocating the size of the buffer dynamically after the size becomes known or by calling `std:fread` multiple times as needed to read in the rest of the data. If allocating the buffer dynamically consider limiting the size to avoid introducing an out of memory exploit for large values, in our example this is not needed because it is already bounded by the size of `uint8_t`.
58
+
In `std:fread` and similar functions, the code may need to read large amounts of data. To handle large data, you can allocate the size of the buffer dynamically after the size becomes known. Or, you can call `std:fread` multiple times as needed to read in the rest of the data. If you allocate the buffer dynamically, consider limiting the size to avoid introducing an out-of-memory exploit for large values. We don't use this approach in our example because it's already bounded by the size of `uint8_t`.
0 commit comments