|
| 1 | +rules: |
| 2 | + - name: no-void-functions |
| 3 | + trigger: >- |
| 4 | + All functions must return a value. Avoid using void return types to ensure |
| 5 | + error values can be propagated upstream. |
| 6 | + solution: >- |
| 7 | + Change the function to return an appropriate error code or result instead |
| 8 | + of void. Ensure all return paths provide a meaningful value. |
| 9 | + - name: avoid-recursion |
| 10 | + trigger: >- |
| 11 | + Recursion is not allowed. Prefer iterative solutions to reduce stack usage |
| 12 | + and prevent potential stack overflows. |
| 13 | + solution: >- |
| 14 | + Refactor the recursive function into an iterative one using loops or other |
| 15 | + control structures. |
| 16 | + - name: use-forcezero |
| 17 | + trigger: >- |
| 18 | + Sensitive data such as private keys must be zeroized using `ForceZero()` |
| 19 | + to prevent the compiler from optimizing away the zeroization. |
| 20 | + solution: >- |
| 21 | + Replace `memset` or similar functions with `ForceZero(variable, size)` to |
| 22 | + ensure sensitive data is properly cleared from memory. |
| 23 | + - name: check-all-return-codes |
| 24 | + trigger: >- |
| 25 | + Every return code from function calls must be checked to handle errors |
| 26 | + appropriately and prevent unexpected behavior. |
| 27 | + solution: >- |
| 28 | + After each function call, add error handling logic to check the return |
| 29 | + value and respond accordingly. |
| 30 | + - name: no-memory-leaks |
| 31 | + trigger: >- |
| 32 | + Memory or resources allocated must have a clear path to being released to |
| 33 | + prevent memory leaks. |
| 34 | + solution: >- |
| 35 | + Ensure that every allocation has a corresponding free or release call. Use |
| 36 | + resource management patterns to handle allocations and deallocations. |
| 37 | + - name: do-not-change-external-apis |
| 38 | + trigger: >- |
| 39 | + External facing APIs should not be altered. Instead of modifying an |
| 40 | + existing API, create a new version with the necessary parameters. |
| 41 | + solution: >- |
| 42 | + If additional parameters are needed, create a new function (e.g., `f_ex(a, |
| 43 | + b)`) and have the original function (`f(a)`) call the new one with default |
| 44 | + or null parameters. |
| 45 | + - name: limit-stack-usage |
| 46 | + trigger: >- |
| 47 | + Functions should not use more than 100 bytes of stack. Excessive stack |
| 48 | + usage can lead to stack overflows and reduced performance. |
| 49 | + solution: >- |
| 50 | + Apply the `WOLFSSL_SMALL_STACK` pattern by dynamically allocating large |
| 51 | + variables to minimize stack usage within the function. |
| 52 | + - name: prefer-constant-time |
| 53 | + trigger: >- |
| 54 | + Implement algorithms in constant time to prevent timing attacks and ensure |
| 55 | + security. |
| 56 | + solution: >- |
| 57 | + Review and refactor algorithms to ensure their execution time does not |
| 58 | + depend on input values. Use constant-time libraries or functions where |
| 59 | + applicable. |
| 60 | + - name: use-sizeof |
| 61 | + trigger: >- |
| 62 | + Avoid hard-coded numeric values for sizes. Use `sizeof()` to ensure |
| 63 | + portability and maintainability. |
| 64 | + solution: >- |
| 65 | + Replace hard-coded sizes with `sizeof(type)` to automatically adapt to |
| 66 | + changes in type sizes. |
| 67 | + - name: use-typedefs-not-stdint |
| 68 | + trigger: >- |
| 69 | + Use `byte`, `word16`, `word32` instead of standard integer types like |
| 70 | + `uint32_t` to maintain consistency across the codebase. |
| 71 | + solution: >- |
| 72 | + Replace instances of `uint32_t` and similar types with the designated |
| 73 | + typedefs such as `word32`. |
| 74 | + - name: use-c-style-comments |
| 75 | + trigger: >- |
| 76 | + Only C-style comments (`/* */`) are allowed in C code. C++ style comments |
| 77 | + (`//`) should not be used. |
| 78 | + solution: >- |
| 79 | + Replace all `//` comments with `/* */` to adhere to the project's |
| 80 | + commenting standards. |
| 81 | + - name: pointer-null-check |
| 82 | + trigger: >- |
| 83 | + Always check for null pointers using the `ptr != NULL` pattern to prevent |
| 84 | + dereferencing null pointers. |
| 85 | + solution: >- |
| 86 | + Add a condition to verify that the pointer is not null before using it, |
| 87 | + e.g., `if (ptr != NULL) { /* use ptr */ }`. |
| 88 | + - name: declare-const-pointers |
| 89 | + trigger: >- |
| 90 | + Pointer parameters that are not modified within a function should be |
| 91 | + declared as `const` to enhance code safety and clarity. |
| 92 | + solution: >- |
| 93 | + Add the `const` keyword to pointer parameters that are not intended to be |
| 94 | + modified, e.g., `const void *ptr`. |
| 95 | + - name: struct-member-order |
| 96 | + trigger: >- |
| 97 | + Struct members should be ordered in descending size to optimize memory |
| 98 | + alignment and reduce padding. |
| 99 | + solution: >- |
| 100 | + Reorder the members of the struct so that larger data types are declared |
| 101 | + before smaller ones. |
| 102 | + - name: no-always-success-stubs |
| 103 | + trigger: >- |
| 104 | + when implementing a stub function that is not fully developed, returning |
| 105 | + success unconditionally can hide real logic and debugging information |
| 106 | + solution: >- |
| 107 | + either implement the stub with real logic or return an appropriate error |
| 108 | + code to indicate "not yet implemented," so that failures are not silently |
| 109 | + ignored |
| 110 | + - name: free-allocated-memory |
| 111 | + trigger: |- |
| 112 | + allocating memory but forgetting to free it on all code paths |
| 113 | + or using functions that allocate buffers without a corresponding free |
| 114 | + solution: >- |
| 115 | + for every XMALLOC call, ensure there's a matching XFREE on every return |
| 116 | + path |
| 117 | +
|
| 118 | + if handing ownership off, confirm the new owner also properly frees it |
| 119 | + - name: check-return-codes |
| 120 | + trigger: >- |
| 121 | + calling library functions that return non-zero in case of error, but not |
| 122 | + checking or handling those return values |
| 123 | + solution: >- |
| 124 | + always verify and handle function return codes |
| 125 | +
|
| 126 | + if ret != 0, do not continue silently; either propagate the error or |
| 127 | + handle it |
| 128 | + - name: handle-partial-writes |
| 129 | + trigger: >- |
| 130 | + calling a write function (e.g., wolfSSL_write_ex) that may write only part |
| 131 | + of the data, returning fewer bytes than requested or a particular status |
| 132 | + solution: >- |
| 133 | + if partial writes are possible, loop until the entire buffer is written or |
| 134 | + an error occurs |
| 135 | +
|
| 136 | + do not assume a single call wrote or accepted all bytes |
| 137 | + - name: manage-ephemeral-objects-correctly |
| 138 | + trigger: >- |
| 139 | + generating or importing ephemeral objects (e.g., ephemeral keys, ephemeral |
| 140 | + certs) and forgetting to finalize or free them, or double-freeing them |
| 141 | + solution: >- |
| 142 | + coordinate ephemeral object ownership carefully |
| 143 | +
|
| 144 | + ensure ephemeral structures are freed once no longer needed, and avoid |
| 145 | + reusing pointers after free |
0 commit comments