Skip to content
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

Fix ResolverProxy use-after-free in HandleNodeBrowse #13291

Merged
merged 1 commit into from
Jan 4, 2022

Conversation

msandstedt
Copy link
Contributor

@msandstedt msandstedt commented Dec 30, 2021

Problem

HandleNodeBrowse decrements the ResolverProxy reference count, which will cause the object to be destructed if the counter reaches 0. But then it increments the counter and accesses the object, which can be a use-after-free.

Fixes #13289

Change overview

This fixes the problem by ordering Release to occur after Retain. This also adds an abort to ReferenceCounted::Retain to check for cases like this when kInitRefCount is non-zero. For objects that are initialized with a non-zero reference count, we don't ever expect to call Retain when the count has already decremented to 0 because this indicates the object has been deleted.

Testing

Tested locally with a modified chip-tool that dynamically creates and initializes ResolverProxy objects for resolve calls, and calls their Shutdown method from within the OnNodeDiscoveryComplete callback. This reliably caused segfault without the fix and did not after. Additional instrumentation was added to log reference counts during testing and it was verified that these were now as expected.

The abort that has been added for ReferenceCounted::Retain should also provide significant coverage.

@github-actions
Copy link

github-actions bot commented Dec 30, 2021

PR #13291: Size comparison from 99c1985 to 3ae2d08

Increases (13 builds for efr32, k32w, linux, p6, qpg, telink)
platform target config section 99c1985 3ae2d08 change % change
efr32 lighting-app BRD4161A (read only) 828924 829212 288 0.0
.text 828916 829204 288 0.0
BRD4161A+rpc (read only) 816552 816856 304 0.0
.text 816544 816848 304 0.0
window-app BRD4161A (read only) 802372 802676 304 0.0
.text 802364 802668 304 0.0
k32w light k32w061+release (read/write) 647440 647456 16 0.0
.text 563552 563568 16 0.0
lock k32w061+release (read/write) 632264 632280 16 0.0
.text 548708 548724 16 0.0
linux chip-tool-ipv6only arm64 (read only) 7010188 7010252 64 0.0
.text 5934516 5934580 64 0.0
thermostat-no-ble arm64 (read only) 2021852 2021884 32 0.0
.text 1680848 1680880 32 0.0
p6 all-clusters-app default (read/write) 2391112 2391384 272 0.0
.text 1349376 1349648 272 0.0
light-app default (read/write) 2323680 2323920 240 0.0
.text 1281944 1282184 240 0.0
lock-app default (read/write) 2295880 2296152 272 0.0
.text 1254144 1254416 272 0.0
qpg lighting-app qpg6105+debug (read only) 531096 531112 16 0.0
.text 525776 525792 16 0.0
lock-app qpg6105+debug (read only) 502876 502900 24 0.0
.text 497556 497580 24 0.0
telink lighting-app tlsr9518adk80d (read/write) 831754 831802 48 0.0
text 580232 580278 46 0.0
Full report (14 builds for efr32, k32w, linux, p6, qpg, telink)
platform target config section 99c1985 3ae2d08 change % change
efr32 lighting-app BRD4161A (read only) 828924 829212 288 0.0
(read/write) 127052 127052 0 0.0
.bss 125176 125176 0 0.0
.data 1876 1876 0 0.0
.text 828916 829204 288 0.0
BRD4161A+rpc (read only) 816552 816856 304 0.0
(read/write) 143720 143720 0 0.0
.bss 141744 141744 0 0.0
.data 1976 1976 0 0.0
.text 816544 816848 304 0.0
window-app BRD4161A (read only) 802372 802676 304 0.0
(read/write) 125992 125992 0 0.0
.bss 124160 124160 0 0.0
.data 1832 1832 0 0.0
.text 802364 802668 304 0.0
k32w light k32w061+release (read/write) 647440 647456 16 0.0
.bss 76184 76184 0 0.0
.data 1904 1904 0 0.0
.text 563552 563568 16 0.0
lock k32w061+release (read/write) 632264 632280 16 0.0
.bss 75896 75896 0 0.0
.data 1860 1860 0 0.0
.text 548708 548724 16 0.0
linux chip-tool-ipv6only arm64 (read only) 7010188 7010252 64 0.0
(read/write) 324849 324849 0 0.0
.bss 54209 54209 0 0.0
.data 1096 1096 0 0.0
.data.rel.ro 208960 208960 0 0.0
.dynamic 560 560 0 0.0
.got 56880 56880 0 0.0
.init 24 24 0 0.0
.init_array 168 168 0 0.0
.rodata 383300 383300 0 0.0
.text 5934516 5934580 64 0.0
thermostat-no-ble arm64 (read only) 2021852 2021884 32 0.0
(read/write) 143937 143937 0 0.0
.bss 63985 63985 0 0.0
.data 880 880 0 0.0
.data.rel.ro 72200 72200 0 0.0
.dynamic 560 560 0 0.0
.got 3936 3936 0 0.0
.init 24 24 0 0.0
.init_array 296 296 0 0.0
.rodata 128476 128476 0 0.0
.text 1680848 1680880 32 0.0
p6 all-clusters-app default (read/write) 2391112 2391384 272 0.0
.bss 116564 116564 0 0.0
.data 2552 2552 0 0.0
.text 1349376 1349648 272 0.0
light-app default (read/write) 2323680 2323920 240 0.0
.bss 105856 105856 0 0.0
.data 2384 2384 0 0.0
.text 1281944 1282184 240 0.0
lock-app default (read/write) 2295880 2296152 272 0.0
.bss 104736 104736 0 0.0
.data 2336 2336 0 0.0
.text 1254144 1254416 272 0.0
qpg lighting-app qpg6105+debug (read only) 531096 531112 16 0.0
(read/write) 146936 146936 0 0.0
.bss 86656 86656 0 0.0
.data 1004 1004 0 0.0
.text 525776 525792 16 0.0
lock-app qpg6105+debug (read only) 502876 502900 24 0.0
(read/write) 146940 146940 0 0.0
.bss 85792 85792 0 0.0
.data 952 952 0 0.0
.text 497556 497580 24 0.0
persistent-storage-app qpg6105+debug (read only) 106448 106448 0 0.0
(read/write) 146938 146938 0 0.0
.bss 36146 36146 0 0.0
.data 288 288 0 0.0
.text 101128 101128 0 0.0
telink lighting-app tlsr9518adk80d (read/write) 831754 831802 48 0.0
bss 86840 86840 0 0.0
noinit 37160 37160 0 0.0
text 580232 580278 46 0.0

HandleNodeBrowse decrements the ResolverProxy reference count, which
will cause the object to be destructed if the counter reaches 0.  It
then increments the counter and accesses the object, which can be a
use-after-free. This commit fixes the problem by ordering Release to
occur after Retain.

This commit also adds an abort to ReferenceCounted::Retain to check for
cases like this when kInitRefCount is non-zero.  For objects that are
initialized with a non-zero reference count, we don't ever expect to
call Retain when the count has already decremented to 0 because this
indicates the object has been deleted.

Fixes project-chip#13289
@github-actions
Copy link

github-actions bot commented Dec 30, 2021

PR #13291: Size comparison from 99c1985 to c50811c

Increases (17 builds for efr32, esp32, linux, mbed, nrfconnect, p6, qpg, telink)
platform target config section 99c1985 c50811c change % change
efr32 lighting-app BRD4161A (read only) 828924 828988 64 0.0
.text 828916 828980 64 0.0
BRD4161A+rpc (read only) 816552 816616 64 0.0
.text 816544 816608 64 0.0
window-app BRD4161A (read only) 802372 802436 64 0.0
.text 802364 802428 64 0.0
esp32 all-clusters-app c3devkit (read only) 882900 882932 32 0.0
.flash.text 882900 882932 32 0.0
m5stack (read only) 943439 943475 36 0.0
.flash.text 938055 938091 36 0.0
linux chip-tool-ipv6only arm64 (read only) 7010188 7010236 48 0.0
.text 5934516 5934564 48 0.0
thermostat-no-ble arm64 (read only) 2021852 2021868 16 0.0
.text 1680848 1680864 16 0.0
mbed lighting-app CY8CPROTO_062_4343W+release (read/write) 2329040 2329104 64 0.0
.text 1291640 1291704 64 0.0
shell CY8CPROTO_062_4343W+release (read/write) 2053888 2053952 64 0.0
.text 1016488 1016552 64 0.0
nrfconnect lighting-app nrf5340dk_nrf5340_cpuapp text 558964 558968 4 0.0
lock-app nrf52840dk_nrf52840 text 609460 609464 4 0.0
pump-controller-app nrf52840dk_nrf52840 text 608208 608212 4 0.0
p6 all-clusters-app default (read/write) 2391112 2391144 32 0.0
.text 1349376 1349408 32 0.0
light-app default (read/write) 2323680 2323712 32 0.0
.text 1281944 1281976 32 0.0
lock-app default (read/write) 2295880 2295912 32 0.0
.text 1254144 1254176 32 0.0
qpg lock-app qpg6105+debug (read only) 502876 502884 8 0.0
.text 497556 497564 8 0.0
telink lighting-app tlsr9518adk80d (read/write) 831754 831770 16 0.0
text 580232 580252 20 0.0
Full report (31 builds for efr32, esp32, k32w, linux, mbed, nrfconnect, p6, qpg, telink)
platform target config section 99c1985 c50811c change % change
efr32 lighting-app BRD4161A (read only) 828924 828988 64 0.0
(read/write) 127052 127052 0 0.0
.bss 125176 125176 0 0.0
.data 1876 1876 0 0.0
.text 828916 828980 64 0.0
BRD4161A+rpc (read only) 816552 816616 64 0.0
(read/write) 143720 143720 0 0.0
.bss 141744 141744 0 0.0
.data 1976 1976 0 0.0
.text 816544 816608 64 0.0
window-app BRD4161A (read only) 802372 802436 64 0.0
(read/write) 125992 125992 0 0.0
.bss 124160 124160 0 0.0
.data 1832 1832 0 0.0
.text 802364 802428 64 0.0
esp32 all-clusters-app c3devkit (read only) 882900 882932 32 0.0
(read/write) 1312498 1312498 0 0.0
.dram0.bss 69104 69104 0 0.0
.dram0.data 14228 14228 0 0.0
.flash.rodata 176104 176104 0 0.0
.flash.text 882900 882932 32 0.0
.iram0.text 62254 62254 0 0.0
m5stack (read only) 943439 943475 36 0.0
(read/write) 441600 441600 0 0.0
.dram0.bss 73600 73600 0 0.0
.dram0.data 34056 34056 0 0.0
.flash.rodata 202936 202936 0 0.0
.flash.text 938055 938091 36 0.0
.iram0.text 122671 122671 0 0.0
k32w light k32w061+release (read/write) 647440 647440 0 0.0
.bss 76184 76184 0 0.0
.data 1904 1904 0 0.0
.text 563552 563552 0 0.0
lock k32w061+release (read/write) 632264 632264 0 0.0
.bss 75896 75896 0 0.0
.data 1860 1860 0 0.0
.text 548708 548708 0 0.0
linux chip-tool-ipv6only arm64 (read only) 7010188 7010236 48 0.0
(read/write) 324849 324849 0 0.0
.bss 54209 54209 0 0.0
.data 1096 1096 0 0.0
.data.rel.ro 208960 208960 0 0.0
.dynamic 560 560 0 0.0
.got 56880 56880 0 0.0
.init 24 24 0 0.0
.init_array 168 168 0 0.0
.rodata 383300 383300 0 0.0
.text 5934516 5934564 48 0.0
thermostat-no-ble arm64 (read only) 2021852 2021868 16 0.0
(read/write) 143937 143937 0 0.0
.bss 63985 63985 0 0.0
.data 880 880 0 0.0
.data.rel.ro 72200 72200 0 0.0
.dynamic 560 560 0 0.0
.got 3936 3936 0 0.0
.init 24 24 0 0.0
.init_array 296 296 0 0.0
.rodata 128476 128476 0 0.0
.text 1680848 1680864 16 0.0
mbed all-clusters-app CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 2338944 2338944 0 0.0
.bss 188364 188364 0 0.0
.data 5272 5272 0 0.0
.text 1301520 1301520 0 0.0
lighting-app CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 2329040 2329104 64 0.0
.bss 180608 180608 0 0.0
.data 5552 5552 0 0.0
.text 1291640 1291704 64 0.0
lock-app CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 2302200 2302200 0 0.0
.bss 179656 179656 0 0.0
.data 5544 5544 0 0.0
.text 1264800 1264800 0 0.0
pigweed-app CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 1140008 1140008 0 0.0
.bss 11756 11756 0 0.0
.data 4368 4368 0 0.0
.text 103392 103392 0 0.0
shell CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 2053888 2053952 64 0.0
.bss 156972 156972 0 0.0
.data 4864 4864 0 0.0
.text 1016488 1016552 64 0.0
nrfconnect lighting-app nrf52840dk_nrf52840 (read/write) 935247 935247 0 0.0
bss 118172 118172 0 0.0
rodata 107996 107996 0 0.0
text 631528 631528 0 0.0
nrf52840dk_nrf52840+rpc (read/write) 921651 921651 0 0.0
bss 115216 115216 0 0.0
rodata 101416 101416 0 0.0
text 626840 626840 0 0.0
nrf5340dk_nrf5340_cpuapp (read/write) 859014 859014 0 0.0
bss 116456 116456 0 0.0
rodata 102924 102924 0 0.0
text 558964 558968 4 0.0
lock-app nrf52840dk_nrf52840 (read/write) 907507 907507 0 0.0
bss 117360 117360 0 0.0
rodata 103304 103304 0 0.0
text 609460 609464 4 0.0
nrf5340dk_nrf5340_cpuapp (read/write) 831422 831422 0 0.0
bss 115672 115672 0 0.0
rodata 98268 98268 0 0.0
text 536940 536940 0 0.0
pigweed-app nrf52840dk_nrf52840 (read/write) 542351 542351 0 0.0
bss 52588 52588 0 0.0
rodata 50668 50668 0 0.0
text 376892 376892 0 0.0
pump-app nrf52840dk_nrf52840 (read/write) 908739 908739 0 0.0
bss 117120 117120 0 0.0
rodata 103520 103520 0 0.0
text 610676 610676 0 0.0
pump-controller-app nrf52840dk_nrf52840 (read/write) 905587 905587 0 0.0
bss 117148 117148 0 0.0
rodata 102776 102776 0 0.0
text 608208 608212 4 0.0
shell nrf52840dk_nrf52840 (read/write) 796871 796871 0 0.0
bss 109536 109536 0 0.0
rodata 78200 78200 0 0.0
text 532680 532680 0 0.0
nrf5340dk_nrf5340_cpuapp (read/write) 709502 709502 0 0.0
bss 107424 107424 0 0.0
rodata 72500 72500 0 0.0
text 450172 450172 0 0.0
p6 all-clusters-app default (read/write) 2391112 2391144 32 0.0
.bss 116564 116564 0 0.0
.data 2552 2552 0 0.0
.text 1349376 1349408 32 0.0
light-app default (read/write) 2323680 2323712 32 0.0
.bss 105856 105856 0 0.0
.data 2384 2384 0 0.0
.text 1281944 1281976 32 0.0
lock-app default (read/write) 2295880 2295912 32 0.0
.bss 104736 104736 0 0.0
.data 2336 2336 0 0.0
.text 1254144 1254176 32 0.0
qpg lighting-app qpg6105+debug (read only) 531096 531096 0 0.0
(read/write) 146936 146936 0 0.0
.bss 86656 86656 0 0.0
.data 1004 1004 0 0.0
.text 525776 525776 0 0.0
lock-app qpg6105+debug (read only) 502876 502884 8 0.0
(read/write) 146940 146940 0 0.0
.bss 85792 85792 0 0.0
.data 952 952 0 0.0
.text 497556 497564 8 0.0
persistent-storage-app qpg6105+debug (read only) 106448 106448 0 0.0
(read/write) 146938 146938 0 0.0
.bss 36146 36146 0 0.0
.data 288 288 0 0.0
.text 101128 101128 0 0.0
telink lighting-app tlsr9518adk80d (read/write) 831754 831770 16 0.0
bss 86840 86840 0 0.0
noinit 37160 37160 0 0.0
text 580232 580252 20 0.0

Copy link

@wbschiller wbschiller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks correct to me.

@andy31415 andy31415 merged commit d4d57f6 into project-chip:master Jan 4, 2022
step0035 pushed a commit to hank820/connectedhomeip that referenced this pull request Feb 8, 2022
)

HandleNodeBrowse decrements the ResolverProxy reference count, which
will cause the object to be destructed if the counter reaches 0.  It
then increments the counter and accesses the object, which can be a
use-after-free. This commit fixes the problem by ordering Release to
occur after Retain.

This commit also adds an abort to ReferenceCounted::Retain to check for
cases like this when kInitRefCount is non-zero.  For objects that are
initialized with a non-zero reference count, we don't ever expect to
call Retain when the count has already decremented to 0 because this
indicates the object has been deleted.

Fixes project-chip#13289
@msandstedt msandstedt deleted the bugfix/13289 branch March 31, 2022 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HandleNodeBrowse ResolverDelegateProxy use-after-free
5 participants