Commit e3a8366
committed
emsmdb: fix use-after-free in ~LOGON_ITEM
LOGON_ITEM::root is going away first, and with it, any information on
node order. Then, as phash.~unordered_map runs, it processes
object_nodes in arbitrary order, freeing a logon_object before a
message_object, but note how ~message_object still wants to use the
logon object.
```
==579226==ERROR: AddressSanitizer: heap-use-after-free on address
0x7d3fa4210ad4 at pc 0x7fcfa5b1a037 bp 0x7ffdf9f81600 sp 0x7ffdf9f815f8
READ of size 1 at 0x7d3fa4210ad4 thread T0
f0 0x7fcfa5b1a036 in gromox::exmdb_client_is_local(char const*, long*) lib/exmdb_client.cpp:438
f1 0x7fcfa8cf86ad in exmdb_client_local::unload_instance(char const*, unsigned int) exch/exmdb/rpc.cpp:991
f2 0x7fcfaabd0c57 in message_object::~message_object() exch/emsmdb/message_object.cpp:183
f3 0x7fcfaae2a22a in object_node::clear() exch/emsmdb/rop_processor.cpp:89
f4 0x7fcfaac05e6e in object_node::~object_node() exch/emsmdb/rop_processor.hpp:35
…
f20 0x7fcfaaae8b06 in LOGON_ITEM::~LOGON_ITEM() exch/emsmdb/rop_processor.hpp:20
f21 0x7fcfaaae8b54 in std::default_delete<LOGON_ITEM>::operator()(LOGON_ITEM*) const /usr/include/c++/15/bits/unique_ptr.h:93
f22 0x7fcfaaae703d in std::unique_ptr<LOGON_ITEM>::~unique_ptr() /usr/include/c++/15/bits/unique_ptr.h:399
f23 0x7fcfaaae5b78 in LOGMAP::~LOGMAP() exch/emsmdb/rop_processor.hpp:25
f24 0x7fcfaaae6287 in emsmdb_info::~emsmdb_info() exch/emsmdb/emsmdb_interface.hpp:17
f25 0x7fcfaaab19c0 in ~HANDLE_DATA exch/emsmdb/emsmdb_interface.cpp:306
…
f32 0x7fcfaaac64af in clear /usr/include/c++/15/bits/unordered_map.h:862
f33 0x7fcfaaab47b7 in emsmdb_interface_stop() exch/emsmdb/emsmdb_interface.cpp:461
0x7d3fa4210ad4 is located 340 bytes inside of 760-byte region [0x7d3fa4210980,0x7d3fa4210c78)
freed by thread T0 here:
f0 operator delete(void*, unsigned long) (/lib64/libasan.so.8+0x12382b)
f1 object_node::clear() exch/emsmdb/rop_processor.cpp:82
f2 object_node::~object_node() exch/emsmdb/rop_processor.hpp:35
…
f26 std::unordered_map<unsigned int, std::shared_ptr<object_node>, std::hash<unsigned int>, std::equal_to<unsigned int>, std::allocator<std::pair<unsigned int const, std::shared_ptr<object_node> > > >::~unordered_map() /usr/include/c++/15/bits/unordered_map.h:112
f27 LOGON_ITEM::~LOGON_ITEM() exch/emsmdb/rop_processor.hpp:20
f28 std::default_delete<LOGON_ITEM>::operator()(LOGON_ITEM*) const /usr/include/c++/15/bits/unique_ptr.h:93
f29 std::unique_ptr<LOGON_ITEM, std::default_delete<LOGON_ITEM> >::~unique_ptr() /usr/include/c++/15/bits/unique_ptr.h:399
f30 LOGMAP::~LOGMAP() exch/emsmdb/rop_processor.hpp:25
f31 emsmdb_info::~emsmdb_info() exch/emsmdb/emsmdb_interface.hpp:17
f32 ~HANDLE_DATA exch/emsmdb/emsmdb_interface.cpp:306
```
We could reorder LOGON_ITEM members, but if `root` is the last holder
of shared_ptr references, there may be a deep call chain for cleanup,
which is probably why phash was first. Add back an explicit
pre-destructor.
Fixes: gromox-1.28-104-g2917d26571 parent 873e897 commit e3a8366
File tree
4 files changed
+14
-2
lines changed- exch/emsmdb
4 files changed
+14
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
179 | 179 | | |
180 | 180 | | |
181 | 181 | | |
182 | | - | |
| 182 | + | |
| 183 | + | |
183 | 184 | | |
184 | 185 | | |
| 186 | + | |
185 | 187 | | |
186 | 188 | | |
187 | 189 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
17 | 22 | | |
18 | 23 | | |
19 | 24 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| 82 | + | |
82 | 83 | | |
83 | 84 | | |
84 | 85 | | |
85 | 86 | | |
| 87 | + | |
86 | 88 | | |
87 | 89 | | |
88 | 90 | | |
| 91 | + | |
89 | 92 | | |
90 | 93 | | |
91 | 94 | | |
| |||
239 | 242 | | |
240 | 243 | | |
241 | 244 | | |
| 245 | + | |
| 246 | + | |
242 | 247 | | |
243 | 248 | | |
244 | 249 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
42 | 41 | | |
| 42 | + | |
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| |||
0 commit comments