Skip to content

kernel: sched: fix possible integer overflow in z_tick_sleep() #92996

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

sudarsan-22
Copy link
Contributor

@sudarsan-22 sudarsan-22 commented Jul 11, 2025

Fix Coverity CID 529867 (CWE-190): z_tick_sleep() may return a large tick count due to wraparound during unsigned tick subtraction.

This patch replaces unsigned subtraction with signed arithmetic to safely handle tick count wraparound and avoid returning incorrect values after timeout abortion.

Fixes: #92601

Fix Coverity CID 529867 (CWE-190): z_tick_sleep() may return a large
tick count due to wraparound during unsigned tick subtraction.

This patch replaces unsigned subtraction with signed arithmetic to
safely handle tick count wraparound and avoid returning incorrect values
after timeout abortion.

Fixes: zephyrproject-rtos#92601

Signed-off-by: sudarsan N <sudarsansamy2002@gmail.com>
Copy link

Copy link
Contributor

@andyross andyross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me like this is going to generate the same code and the same operations: it does a uint32_t subtraction and manually checks for overflow by casting the results to int32_t and looking at the sign.

What's the argument for why Coverity won't just flag it again? If the argument is "Coverity is too dumb to notice this new code", then IMHO the proper solution is to filter the test and not just rearrange the code.

If you need to test for overflow in unsigned math in a robust way, the solution is generally something like:

if (a > b) return a - b else return 0;

@sudarsan-22
Copy link
Contributor Author

It looks to me like this is going to generate the same code and the same operations: it does a uint32_t subtraction and manually checks for overflow by casting the results to int32_t and looking at the sign.

What's the argument for why Coverity won't just flag it again? If the argument is "Coverity is too dumb to notice this new code", then IMHO the proper solution is to filter the test and not just rearrange the code.

If you need to test for overflow in unsigned math in a robust way, the solution is generally something like:

if (a > b) return a - b else return 0;

Thanks Andy for the review!

You're right — the updated code still performs unsigned subtraction internally, and it's possible that Coverity may flag this again despite the cast.

The explicit check you suggested using:

if (expected_wakeup_ticks > now) {
return expected_wakeup_ticks - now;
} else {
return 0;
}
which is ok ?

@sudarsan-22 sudarsan-22 requested a review from andyross July 17, 2025 09:30
@andyross
Copy link
Contributor

If you're able to run coverity locally, then the right answer is "whatever works to silence the error". If not, sticking to defined behavior is best, and what you wrote in your comment looks correct to me. Sleeping isn't in general a performance path so we don't need to care too much about generated code quality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Coverity CID: 529867] Overflowed return value in kernel/sched.c
3 participants