-
Notifications
You must be signed in to change notification settings - Fork 514
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
duk_api_stack: increase memory safety #2563
duk_api_stack: increase memory safety #2563
Conversation
The ptr_diff is taken between the post reallocation new_valstack pointer and pre-allocation thr->valstack pointer variables. This is in principle wrong as the realloc function might change the base pointer, which appears to be the assumption here that it will not. Further on this difference is then added to the old base pointers for bottom/top/end thr->valstack variables, with only thr->valstack being repalced with the new base pointer. So we have the difference between two base pointers added to the old base pointer effectively as if the memory was contiguous. Lets change that and add the pointer differences to the new_valstack base pointer obtained from the realloc function instead. Signed-off-by: Pawel Zalewski <pzalewski@thegoodpenguin.co.uk>
No, that's not assumed by the code. So for example, suppose:
Same applies to the other pointers. Perhaps a better name for |
Oh I am a numpty, thank you for spelling it out for me. The commit message is based on my old notes, which are outdate and only the first sentence is relevant. My apologies I might be too old for this.. The problem here is that post realloc the old pointer is invalid as that memory could have been deallocated, yet that adress is used here for arithmetic - mathematically nothing wrong with it, as proven above, semantically in terms of C standard this is undefined. The pointer difference should be taken between two valid pointers.This is in section 6.2.4 of the standard on storage durations of objects. The second issue is that even if the two pointers were valid, the difference is taken between two allocations, which is also against the standard C. I know that a pointer is just an address/integer but... Some context: I have been using duktape via Zabbix on an ARM Morello, implementation of CHERI architecture, where a pointer is a new datatype at the architecture level and is of size 16 not 8 bytes. The pointer you get after realloc is effectively a new data object with its bounds metadata set in hardware, thus adding an offset to the old pointer object is not longer even possible as you will violate the old bounds and get a segfault. So the C standard is enforced by hardware in this case one could say. Good news is that after implementing alingment to 16 and fixing the above offset issue duktape had no runtime issues thus far on this hardware (please note this was by no means full coverage just normal usage - but self test did pass). So the above patch would future proof that routine for CHERI based platforms and make the code std C compliant. Your proposition of renaming the ptr_diff variable is very good, if you would rather keep it the way it is for now. However the issue remains that the original pointer after realloc is not a valid pointer in std C as it points to deallocated memory, so one should try not to operate on it at all as it is possible that its integer address could be undefined, so you can be at the mercy of the compiler effectively which is not a great place to be. Again sorry for the original commit message, it is wrong and needs to be corrected. |
Thanks for the clarifications, could you comment on this:
So do you mean that it's undefined behavior just to do pointer arithmetic on the old pointer? It's clear that dereferencing it is undefined behavior, but is mere arithmetic also prohibited? I'm not a standards expert but this would break a lot of common practice like using C99 Section 6.2.4 says this:
But I understand it as referring to the object, i.e. dereferencing the pointer and not just holding/computing with it.
This sounds quite interesting :-) |
So the full body of paragraph 2 in section 6.2.4 is:
From this my understanding is that the |
Closing as there is no interest in this. |
The ptr_diff is taken between the post reallocation new_valstack pointer and pre-allocation thr->valstack pointer variables. Realloc function might change the base pointer, so there might be a difference between thr->valstack and new_valstack, which appears to be the assumption here that this will not be the case ?
Further on this difference is then added to the old base pointers for bottom/top/end thr->valstack variables, with only thr->valstack being repalced with the new base pointer. So we have the difference between two base pointers added to the old base pointer effectively as if the memory was contiguous.
Lets change that and add the pointer differences to the new_valstack base pointer obtained from the realloc function instead.