-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CodeQL -- Actual fixes #2720
base: master
Are you sure you want to change the base?
CodeQL -- Actual fixes #2720
Conversation
Code was previously performing arithmetic in various loop check conditions. Integer promotion rules could cause unintended comparisons. `spiffs` defined `fs->block_count` as `uint32_t`, but defined `spiffs_page_ix` as `uint16_t`. Various overflow checks detected by CodeQL and fixed by checking for those conditions before looping.
The compiler warning is incorrect. Since `calloc()` zero's memory, can remove redundant line setting value to zero, giving quieter builds.
@@ -535,26 +535,61 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) { | |||
|
|||
s32_t res = SPIFFS_OK; | |||
spiffs_page_ix pix_offset = 0; | |||
// Avoid arithmetic in loop conditions (integer promotion rules can cause unintended consequences) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please have second set of eyes review these checks.
@@ -114,8 +114,10 @@ static int EmSendCmdThinfilmRaw(const uint8_t *resp, uint16_t respLen) { | |||
} | |||
|
|||
// Ensure that the FPGA Delay Queue is empty | |||
uint8_t fpga_queued_bits = FpgaSendQueueDelay >> 3; | |||
for (i = 0; i <= (fpga_queued_bits >> 3) + 1;) { | |||
uint16_t fpga_queued_bits = FpgaSendQueueDelay >> 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
explicitly use unsigned values for the maths, and store back as uint16_t
. This allows the for()
loop to index on a variable of size uint16_t
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
keep_field_on = i < ndef_size + offset - max_rapdu_size; | ||
aREAD_NDEF_n = 0; | ||
param_gethex_to_eol("00b00000", 0, aREAD_NDEF, sizeof(aREAD_NDEF), &aREAD_NDEF_n); | ||
aREAD_NDEF[2] = i >> 8; | ||
aREAD_NDEF[3] = i & 0xFF; | ||
|
||
// Segment_size is stuffed into a single-byte field below ... so error out if overflows |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If previous code ever had a segment_size
greater than 0xFF
, then the old code would have silently truncated the value. After review, this appeared to be incorrect behavior, and that there was an implicit assumption that segment_size
would always be single-byte value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proper solution would not to use size_t but u32 and look into the ndef standard to handle larger than 0xFF sized segments?
|
||
// empty e_sector | ||
for (size_t i = 0; i < items; i++) { | ||
for (uint8_t j = 0; j < 2; j++) { | ||
(*src)[i].Key[j] = 0xffffffffffff; | ||
(*src)[i].foundKey[j] = 0; | ||
// (*src)[i].foundKey[j] = 0; // calloc zero's these already |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I cannot explain why CodeQL alerted on this line, and therefore cannot explain why its removal makes CodeQL happier. But, it's redundant since calloc()
ensures memory is zero at allocation, so ... removal is OK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true , still shows that codeQL has false positives
@@ -245,7 +245,7 @@ static int ask_em410x_binary_decode(bool verbose, uint32_t *hi, uint64_t *lo, ui | |||
else if (ans == -4) | |||
PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x preamble not found"); | |||
else if (ans == -5) | |||
PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x Size not correct: %zu", size); | |||
PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x Size not correct: %zu", *size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size
was a pointer to the size, not the size itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
This is supported for GCC >= version 13 See GCC bug 85487: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85487
0); | ||
// traverse each page except for lookup pages | ||
spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_PAGES(fs) + SPIFFS_PAGES_PER_BLOCK(fs) * cur_block; | ||
while (!restart && cur_pix < SPIFFS_PAGES_PER_BLOCK(fs) * (cur_block + 1)) { | ||
while (!restart && cur_pix < total_blocks_plus_one_page) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one says "cur_block + 1" vs "total_blocks_plus_one_page" ???
spiffs_block_ix bix = 0; | ||
while (bix < fs->block_count) { | ||
while (bix < block_count) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it really that block_count is large, or ?
block_count = 0, nothing happens,
if large number, the spiff_ok check should fail when trying to erase a block outside of existing once..
not sure how this would be a infinite loop?
uint8_t fpga_queued_bits = FpgaSendQueueDelay >> 3; | ||
for (i = 0; i <= (fpga_queued_bits >> 3) + 1;) { | ||
uint16_t fpga_queued_bits = FpgaSendQueueDelay >> 3; | ||
fpga_queued_bits /= 8u; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the >>> 3
for consistency. Once upon a time we didn't want to trigger floats inside the arm code because of size.
|
||
// This allocates based on the size of a single item | ||
_Static_assert(sizeof(sector_t) >= 18, "Unexpectedly small sector_t"); // if packed, would be 18 | ||
_Static_assert(sizeof(sector_t) == 24, "Sector_t used to be padded to 24 bytes?"); // not packed, so each entry must be 24 bytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code looks more like debug code.
// ISSUE: C99 has no _Static_assert() ... was added in C11
PrintAndLogEx(WARNING, "word count was: %d, limiting to %d", now, EM4X50_NO_WORDS); | ||
now = EM4X50_NO_WORDS; | ||
} | ||
|
||
if (now > 0) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one can be " if (now) {
PrintAndLogEx(WARNING, "word count was: %d, limiting to %d", now, EM4X50_NO_WORDS); | ||
now = EM4X50_NO_WORDS; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the proper fix would be not misusing the return status code and check it accordingly
Many of the CodeQL bugs of type "Comparison between A of TypeA and B of wider type TypeB" were caused by having arithmetic within a
for()
loop's comparison clause. Not only were the operations redundant, but they could cause unintended consequences (e.g., integer promotion rules). Relatively simple to fix (use larger of two sizes for loop variable, compare unsigned vs. unsigned, etc.).The other reason for many of these was that spiffs, in the definition of
struct spiffs_t
, defined fieldblock_count
of typeuint32_t
, but defined fieldfree_cursor_block_ix
to be of typespiffs_block_ix
. In PM3,spiffs_block_ix
is defined asuint16_t
. Thus, a variable of typespiffs_block_ix
cannot directly loop againstblock_count
(potential infinite loops).Inline "conversation"s added below, both to explain some changes, and to mark code that should have a second set of eyes review.