-
Notifications
You must be signed in to change notification settings - Fork 0
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
STL vector 0-byte overlap #2
Comments
I am not sure if I understand the bug. In my option, the root cause is because one chunk's start address is another chunk's end address. It means the two chunk have a "0-byte overlap". The bug is crazy, it may means we can not use tcmalloc, because the memory allocated by tcmalloc is completely contiguous but ptmalloc not. |
I have another method, we can reserve 8-byte address at the end of chunk at any time. Then chunks in memory will not be contiguous. |
We can even use the reserved area as 'heap canary`. |
How this overlap happened: link |
reproduction case: compile it by #include<vector>
#include<iostream>
char data[0x9] = "aaaaaaaa";
void trigger(){
std::vector<std::string> v;
v.push_back(std::string(data));
printf("\nv._M_impl._M_start: %#lx\nv._M_impl._M_end: %#lx\nv._M_impl._M_end_of_storage: %#lx\n\n",*(unsigned long *)((char *)&v+0),*(unsigned long *)((char *)&v+8),*(unsigned long *)((char *)&v+0x10));
std::vector<std::string> v2;
v2.push_back(std::string(data));
printf("\nv2._M_impl._M_start: %#lx\nv2._M_impl._M_end: %#lx\nv2._M_impl._M_end_of_storage: %#lx\n\n",*(unsigned long *)((char *)&v2+0),*(unsigned long *)((char *)&v2+8),*(unsigned long *)((char *)&v2+0x10));
}
int main(){
std::vector<std::string> args;
args.push_back(std::string(data));
printf("\nargs._M_impl._M_start: %#lx\nargs._M_impl._M_end: %#lx\nargs._M_impl._M_end_of_storage: %#lx\n\n",*(unsigned long *)((char *)&args+0),*(unsigned long *)((char *)&args+8),*(unsigned long *)((char *)&args+0x10));
trigger();
}
|
In ptmalloc, this kind of vector overlap won't happen, in violet it will happen. violet:
native clang++
|
The escape is meant to be simple and light, we shouldn’t make it too
complex.
…On Sun, Oct 9, 2022 at 13:40 dataisland ***@***.***> wrote:
We can even use the reserved area as 'heap canary`.
—
Reply to this email directly, view it on GitHub
<#2 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEOMNZO2XIHBZWPNHNNSBRTWCMGSDANCNFSM6AAAAAARAYKGA4>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Basically, in cnedfunction.cc,
void cNEDFunction::parseSignature(const char *signature)
In the end of
splitTypeAndName
,~vector -> ~_Vector_base
will finally be called to_M_deallocate
,At this time, the
std::vector<std::string> v
create insplitTypeAndName
is going to be deallocated,however, when the local
std::vector<std::string> v
being deallocated:Notice that
v._M_start = 0x147d7fa20400
which equals toargs._M_impl._M_finish = 0x147d7fa20400
Because of that when v._M_start = 0x147d7fa20400 is poisioned, it will affect args._M_impl like:
which means that
args._M_impl._M_finish = args._M_impl._M_end_of_storage = v._M_impl._M_start = 0cdeadbeefdeadbeef
After we reach the end of
parseSignature
,~vector
will also be called to deallocatestd::vector<std::string> args
But because the poison, the args is like:
Which is obviously invalid.
The escape bug in this case can be triggered and expounded through the gdb script:
The text was updated successfully, but these errors were encountered: