Fix type mismatch in new/delete of addrinfo::ai_addr#2136
Fix type mismatch in new/delete of addrinfo::ai_addr#2136kenballus wants to merge 1 commit intosquid-cache:masterfrom kenballus:master
Conversation
|
The relevant UBSan error: |
src/ip/Address.cc
Outdated
There was a problem hiding this comment.
Thank you for attacking this bug! PR #1671 tried to fix this problem as well, but used ai_addrlen unstead of ai_family to figure out the right type. It was later decided that using ai_addrlen is not the right answer because its value is unreliable. I have not checked whether ai_family may suffer from similar problems.
- If ai_family suffers from similar problems, then PR 1671 proposed long-term solution (i.e. get rid of these dynamic allocations) is probably still the best way forward.
- Otherwise, PR 1671-like changes that isolate ai_addr allocations/deallocations and warn us about unsupported ai_family values are warranted in this PR. See AllocateAddrMember() and FreeAddrMember() functions there.
@kenballus, do you think ai_family is always correct in this context? If yes, please incorporate AllocateAddrMember() and FreeAddrMember() changes from #1671 while using ai_family instead of ai_addrlen. Doing so will, among other positive effects, fix one delete case that this PR have missed. Please also borrow PR 1671 title/description, with any necessary adjustments.
There was a problem hiding this comment.
I think the easiest solution here is just to new and delete as struct sockaddr_storage. This means that new/delete always match, but the rest of the code doesn't need to change.
Just force-pushed.
There was a problem hiding this comment.
Unfortunately, I don't think ai_family is reliable. For some reason, the patch didn't behave as expected when I checked ai_family against AF_INET6. Best path forward is probably just to ensure that allocation/deallocation doesn't need to know anything about the type of the struct other than its size.
There was a problem hiding this comment.
@rousskov do you think this is a suitable solution to the problem? I'd prefer not to make sweeping changes here if they can be avoided.
There was a problem hiding this comment.
@rousskov do you think this is a suitable solution to the problem?
I need more time to answer your question.
I'd prefer not to make sweeping changes here if they can be avoided.
I believe you and I share that preference, although our definitions of "sweeping changes" may differ :-). At any rate, the currently proposed sockaddr_storage-based solution deserves a consideration, at least as a starting point. Please give me a few workdays to come back and review it properly.
There was a problem hiding this comment.
I believe you and I share that preference, although our definitions of "sweeping changes" may differ :-)
Basically anything more than a few lines is "sweeping" to me :)
At any rate, the currently proposed sockaddr_storage-based solution deserves a consideration, at least as a starting point.
This is the solution that the Linux kernel took to a similar problem. See https://lwn.net/Articles/997094/
Please give me a few workdays to come back and review it properly.
Of course.
Thanks!
Ben
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
new/delete type mismatches are UB. Fix an instance of this problem that occurs when sockaddr_in6 is allocated, but sockaddr is deallocated, by always allocating/deallocating sockaddr_storage.
|
@rousskov , LGTM over to you now. |
rousskov
left a comment
There was a problem hiding this comment.
I cannot think of a better surgical solution to this problem. Thank you.
new/delete type mismatches are UB. Fix an instance of this
problem that occurs when sockaddr_in6 is allocated, but
sockaddr is deallocated, by always allocating/deallocating
sockaddr_storage.
AddressSanitizer: new-delete-type-mismatch:
object passed to delete has wrong type:
size of the allocated type: 28 bytes;
size of the deallocated type: 16 bytes.
#0 0xaaaad1a8db54 in operator delete(void*, unsigned long)
#1 0xaaaad287a668 in Ip::Address::FreeAddr(addrinfo*&)
src/ip/Address.cc:710:22
new/delete type mismatches are UB. Fix an instance of this
problem that occurs when sockaddr_in6 is allocated, but
sockaddr is deallocated, by always allocating/deallocating
sockaddr_storage.
AddressSanitizer: new-delete-type-mismatch:
object passed to delete has wrong type:
size of the allocated type: 28 bytes;
size of the deallocated type: 16 bytes.
#0 0xaaaad1a8db54 in operator delete(void*, unsigned long)
squid-cache#1 0xaaaad287a668 in Ip::Address::FreeAddr(addrinfo*&)
src/ip/Address.cc:710:22
new/delete type mismatches are UB. Fix an instance of this
problem that occurs when sockaddr_in6 is allocated, but
sockaddr is deallocated, by always allocating/deallocating
sockaddr_storage.
AddressSanitizer: new-delete-type-mismatch:
object passed to delete has wrong type:
size of the allocated type: 28 bytes;
size of the deallocated type: 16 bytes.
#0 0xaaaad1a8db54 in operator delete(void*, unsigned long)
#1 0xaaaad287a668 in Ip::Address::FreeAddr(addrinfo*&)
src/ip/Address.cc:710:22
|
queued for backport to v7 |
7 similar comments
|
queued for backport to v7 |
|
queued for backport to v7 |
|
queued for backport to v7 |
|
queued for backport to v7 |
|
queued for backport to v7 |
|
queued for backport to v7 |
|
queued for backport to v7 |
new/delete type mismatches are UB. Fix an instance of this
problem that occurs when sockaddr_in6 is allocated, but
sockaddr is deallocated, by always allocating/deallocating
sockaddr_storage.