-
Notifications
You must be signed in to change notification settings - Fork 6.6k
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
syscalls: arm: Fix possible overflow in is_in_region function #23239
Conversation
@ceolin I've restarted Shippable a few times, but still keeps failing - is it because of something in this PR? |
Answering myself: seems like it is:
|
@jhedberg there are two issues that we need to figure out how to handle
any thoughts ? |
return 0; | ||
} | ||
|
||
if (start >= r_addr_start && end <= r_addr_end) { |
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.
here, 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.
and i the nxp_mpu.c
@andyross @andrewboie ideas ? |
@@ -216,7 +217,11 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size) | |||
MPU_RASR_SIZE_Pos) + 1; | |||
r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1; | |||
|
|||
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) { | |||
if (size == 0 || __builtin_add_overflow(start, size - 1, &end)) { |
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.
Also, if you want the function to return false when size is zero, I believe this needs to be documented.
Furthermore, I think the case of zero "size", should be better checked at the caller function, mpu_buffer_validate, or even documented as a non-allowed input in the common arch interface API, arch_buffer_validate. @andrewboie what do you think?
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.
yeah, that is weird, but I believe x86 works same way, I'll change the pr to allows size 0, what means just check whether or not the buffer address is in the given region. This will fix the problem and keeps the current behavior
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.
whether or not allow size 0 can be addressed / discussed later to no block the release, since it seems not to be a bug. The questions regarding poll and pipe behavior are still open IMHO.
This function is widely used by functions that validate memory buffers. Macros used to check permissions, like Z_SYSCALL_MEMORY_READ and Z_SYSCALL_MEMORY_WRITE, use these functions to check that a pointers passed by user threads in a syscall. Signed-off-by: Flavio Ceolin <[email protected]>
@ioannisg @stephanosio are you guys ok with the latest version of this PR? I'd like some more reviews than just my own before merging. |
Will check this again early tomorrow morning @jhedberg |
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.
@ceolin correct me if I am wrong, but now, it seems that supplying a zero sized buffer will result in the function returning true.This is a change compared to the original behavior, so I wonder if we need that.
could this PR just fix the overflow issue?
We were wrongly accepting size 0. Now, at least we are not comparing an address out of the "valid" range. My initial patch was not accepting size == 0 but then it broke some tests and the behavior was different from X86. My suggestion is merge it and fix the problems and then we can decide whether or not accept 0 size buffers, this will apply to X86 and ARC as well. |
I understand the behavior, but not the semantics. Why is the test passing a 0 buffer in the first place? What is it testing? |
The test is testing this corner case what is valid. It is a boundary that has to be tested, the problem is if we reject 0 size buffer at memory access level we trigger an exception what the tests and APIs don't expect |
So is a 0 size buffer valid or not? |
And what does it mean to call these APIs with a 0 size buffer? |
That is the trick part, currently it is, but not explicitly. Regarding the second question, the meaning is per basis API. Take a look in
According with it, if |
I see. Maybe for footprint/performance reasons we should leave (and document in the header) that arch_buffer_validate() on a 0-sized region is undefined behavior, and for these particular syscalls add explicit checks. What do you think? We can contemplate this for another PR. Regardless of what we decide, the API docs should be updated. |
Agree. Further we can have the initial patch that invalidates 0 size buffers and properly fix APIs. Do you want me to update this commit with that info ? |
@andrewboie @ceolin I would like us to update the API and agree on the behavior when the passed size is zero before merging this PR, since this is an essential part of the patch. Ideally, I would like the test-cases and the doc-fix to come within this PR :) |
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, submit also the fix for API documentation, as well as a test that covers this corner case of zero size.
doing it. |
what exactly you want here ? I'll document that 0 size buffer is undefined behavior, we should not have test for it. That's said, pipe and poll tests are exercising this case, my opinion is that we fix these APIs (maybe others) later. |
Documenting that 0 size buffer has undefined behavior. See: zephyrproject-rtos#23239 Signed-off-by: Flavio Ceolin <[email protected]>
It's not like this UB represents a security concern unless I'm missing something. Should not block this PR. |
@@ -578,6 +578,8 @@ void arch_mem_domain_destroy(struct k_mem_domain *domain); | |||
* if the supplied memory buffer spans multiple enabled memory management | |||
* regions (even if all such regions permit user access). | |||
* | |||
* @warning 0 size buffer has undefined behavior. |
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.
That's exactly what I wanted :)
Since we are now documenting that arch_buffer_validate cannot get a 0 size buffer, we need to open an issue for fixing the APIs related to the tests mentioned above |
Documenting that 0 size buffer has undefined behavior. See: zephyrproject-rtos#23239 Signed-off-by: Flavio Ceolin <[email protected]>
Documenting that 0 size buffer has undefined behavior. See: zephyrproject-rtos#23239 Signed-off-by: Flavio Ceolin <[email protected]>
Documenting that 0 size buffer has undefined behavior. See: zephyrproject-rtos#23239 Signed-off-by: Flavio Ceolin <[email protected]>
Documenting that 0 size buffer has undefined behavior. See: #23239 Signed-off-by: Flavio Ceolin <[email protected]>
Documenting that 0 size buffer has undefined behavior. See: #23239 Signed-off-by: Flavio Ceolin <[email protected]>
This function is widely used by functions that validate memory
buffers. Macros used to check permissions, like Z_SYSCALL_MEMORY_READ
and Z_SYSCALL_MEMORY_WRITE, use these functions to check that a
pointers passed by user threads in a syscall.
Signed-off-by: Flavio Ceolin [email protected]