-
Notifications
You must be signed in to change notification settings - Fork 349
modules: Apparently asking 0 alignment is dangerous, use 4 as default #10324
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
base: main
Are you sure you want to change the base?
Conversation
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.
Pull Request Overview
This PR fixes a potential division by zero error in memory allocation functions by changing the default alignment parameter from 0 to 4. The issue occurs because the underlying rballoc_align() implementation uses Zephyr's IS_ALIGNED() macro, which performs a modulo operation that would fail with a zero alignment value.
Key Changes:
- Updated
mod_balloc()to pass alignment of 4 instead of 0 - Updated
mod_alloc()to pass alignment of 4 instead of 0
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
d8f93c0 to
b5ddf37
Compare
The current rballoc_align() implementation has this line: assert(IS_ALIGNED(mem, align)); Which will cause division by zero due to IS_ALIGNED() Zephyr implementation: define IS_ALIGNED(ptr, align) (((uintptr_t)(ptr)) % (align) == 0) So better use sizeof(void *) as the default value. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
b5ddf37 to
17e871c
Compare
softwarecki
left a comment
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.
Using 0 as an alignment value might intuitively suggest "no alignment" or "not meaningful", but it could also be interpreted as an invalid value.
Any valid alignment can be expressed using 1 instead.
Defaulting to pointer-sized alignment seems like a reasonable and safe choice.
abonislawski
left a comment
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.
Thanks, much better than modified macro
kv2019i
left a comment
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.
CI failure seen, otherwise ready to go.
No, this is sporadic problem seen in many others PR |
Can we rerun @lrudyX ? thanks. |
lyakh
left a comment
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.
Fixing it at the actual failure location could be a better option
| { | ||
| return mod_balloc_align(mod, size, 0); | ||
| /* IS_ALIGNED() crashes if alignment is 0, so use pointer size as default alignment */ | ||
| return mod_balloc_align(mod, size, sizeof(void *)); |
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 this because of
Line 296 in a86f371
| assert(IS_ALIGNED(mem, align)); |
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.
Possibly both places. But defaulting to ptr size alignment is a sane thing to do even if there was no assert there.
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.
Possibly both places. But defaulting to ptr size alignment is a sane thing to do even if there was no assert there.
@jsarha but why here? This is way too high a level imho. This is just a module allocation wrapper. In principle - yes, I'd agree, that allocating with less than 4 bytes alignment isn't very meaningful, and I actually suspect this is already the case with Zephyr heap allocator. So, doesn't seem to make much sense to me here.
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.
@lyakh, I do not want to have parallel mod_alloc implementations for specified alignment and unspecified alignment, so I need to implement mod_alloc_align() and call it from mod_alloc(). In that call I have to specify the default alignment and sizeof(void *) is a sane default.
There is still a strong argument to fix the rballoc_align() implementation so that it would not crash with zero alignment argument, or even fixing the Zephyr IS_ALIGNED() macro so that it would not crash if align argument is zero. But those valid fixes do not make this change invalid.
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.
@jsarha sorry, I still don't find this useful. Forcing a sizeof(void *) alignment in just one of high level allocation APIs seems too random to me, while we have a (perceived) bug in a specific place that should be fixed. And fixing it in two locations appears redundant to me too.
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.
@lyakh , Ok, would you then let default alignment of 1 to pass? I feel that alignment of 1 would really be an odd choice, but not as odd as 0. Or should I just close this PR? Its not like any of my PR are moving any more.
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.
Lets fix this in this PR, alignment "0" is simply wrong
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.
@jsarha @abonislawski I think it's rather common to use 0 to mean "no explicit alignment," e.g. https://github.com/zephyrproject-rtos/zephyr/blob/a0096b719c22e1af818f56f6ae0657c1635c3cf0/kernel/kheap.c#L136 or
Line 489 in a86f371
| return rmalloc_align(flags, bytes, 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.
Upon checking it looks like alignment 0 is present in some zephyr docs, in that case our assert call for IS_ALIGNED is too general and needs an additional condition
|
|
Ok, here is an alternative solution. We need one or the other, preferrably soon. So please agree on either one (I would still vote for both). |
The current rballoc_align() implementation has this line:
assert(IS_ALIGNED(mem, align));
Which will cause division by zero due to IS_ALIGNED() Zephyr implementation:
define IS_ALIGNED(ptr, align) (((uintptr_t)(ptr)) % (align) == 0)
So better use 4 as the default value.