Skip to content

Fix stack-use-after-scope reading QT_QPA_PLATFORM env var #3531

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

Merged
merged 1 commit into from
Feb 5, 2025

Conversation

Smjert
Copy link
Contributor

@Smjert Smjert commented Feb 5, 2025

Description

Building with Asan on Linux and starting qrenderdoc causes an immediate crash.

Setting QT_QPA_PLATFORM with putenv from a local variable causes the environment to later still refer to it when it's out of scope. Use setenv instead, as it copies the values provided.

Asan output:

=================================================================
==186532==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fad55b1acf0 at pc 0x7fad62676cb1 bp 0x7ffed4d0bda0 sp 0x7ffed4d0b548
READ of size 4 at 0x7fad55b1acf0 thread T0
    #0 0x7fad62676cb0 in strlen /usr/src/debug/gcc/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:391
    #1 0x7fad5b13fb10 in QByteArray::QByteArray(char const*, int) (/usr/lib/libQt5Core.so.5+0x13fb10) (BuildId: ea54d08e6101ccb20735d0238686c8f8aab9e1f8)
    #2 0x7fad5b0e37dc in qgetenv(char const*) (/usr/lib/libQt5Core.so.5+0xe37dc) (BuildId: ea54d08e6101ccb20735d0238686c8f8aab9e1f8)
    #3 0x7fad5b73208d in QGuiApplicationPrivate::createPlatformIntegration() (/usr/lib/libQt5Gui.so.5+0x13208d) (BuildId: 4303ae81f380b376ed634b87a7d226266b7f1eba)
    #4 0x7fad5b733b10 in QGuiApplicationPrivate::createEventDispatcher() (/usr/lib/libQt5Gui.so.5+0x133b10) (BuildId: 4303ae81f380b376ed634b87a7d226266b7f1eba)
    #5 0x7fad5b2b682c in QCoreApplicationPrivate::init() (/usr/lib/libQt5Core.so.5+0x2b682c) (BuildId: ea54d08e6101ccb20735d0238686c8f8aab9e1f8)
    #6 0x7fad5b733bc6 in QGuiApplicationPrivate::init() (/usr/lib/libQt5Gui.so.5+0x133bc6) (BuildId: 4303ae81f380b376ed634b87a7d226266b7f1eba)
    #7 0x7fad5bf53735 in QApplicationPrivate::init() (/usr/lib/libQt5Widgets.so.5+0x153735) (BuildId: 7b13dd81cdd603e649fac765c9b95098c6cc82b8)
    #8 0x5e534c7feab5 in main ../../qrenderdoc/Code/qrenderdoc.cpp:317
    #9 0x7fad5aa35487  (/usr/lib/libc.so.6+0x27487) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #10 0x7fad5aa3554b in __libc_start_main (/usr/lib/libc.so.6+0x2754b) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #11 0x5e534bc62144 in _start (/home/smjert/Development/renderdoc/build/bin/qrenderdoc+0xed1144) (BuildId: 000f3714b99c3395df4f6bd63614aa068280c136)

Address 0x7fad55b1acf0 is located in stack of thread T0 at offset 11504 in frame
    #0 0x5e534c7fd0f3 in main ../../qrenderdoc/Code/qrenderdoc.cpp:184

  This frame has 245 object(s):
    [48, 49) '<unknown>'
    [64, 65) '<unknown>'
    [80, 81) '<unknown>'
    [96, 97) '<unknown>'
    [112, 113) '<unknown>'
    [128, 129) '<unknown>'
    [144, 145) '<unknown>'
    [160, 161) '<unknown>'
    [176, 177) '<unknown>'
    [192, 193) '<unknown>'
    [208, 209) '<unknown>'
    [224, 225) '<unknown>'
    [240, 241) '<unknown>'
    [256, 257) '<unknown>'
    [272, 273) '<unknown>'
    [288, 289) '<unknown>'
    [304, 305) '<unknown>'
    [320, 321) '<unknown>'
    [336, 337) '<unknown>'
    [352, 353) '<unknown>'
    [368, 369) '<unknown>'
    [384, 385) '<unknown>'
    [400, 401) '<unknown>'
    [416, 417) '<unknown>'
    [432, 433) '<unknown>'
    [448, 449) '<unknown>'
    [464, 465) '<unknown>'
    [480, 481) '<unknown>'
    [496, 497) '<unknown>'
    [512, 513) 'ok' (line 430)
    [528, 529) '<unknown>'
    [544, 545) '<unknown>'
    [560, 561) '<unknown>'
    [576, 577) '<unknown>'
    [592, 593) '<unknown>'
    [608, 609) '<unknown>'
    [624, 625) '<unknown>'
    [640, 641) '<unknown>'
    [656, 657) '<unknown>'
    [672, 673) '<unknown>'
    [688, 689) '<unknown>'
    [704, 705) '<unknown>'
    [720, 721) 'pythonExited' (line 667)
    [736, 738) '<unknown>'
    [752, 754) '<unknown>'
    [768, 770) '<unknown>'
    [784, 786) '<unknown>'
    [800, 804) '<unknown>'
    [816, 820) '<unknown>'
    [832, 836) '<unknown>'
    [848, 852) '<unknown>'
    [864, 868) '<unknown>'
    [880, 884) '<unknown>'
    [896, 900) '<unknown>'
    [912, 916) '<unknown>'
    [928, 932) 'argc' (line 183)
    [944, 952) '<unknown>'
    [976, 984) '<unknown>'
    [1008, 1016) '<unknown>'
    [1040, 1048) '<unknown>'
    [1072, 1080) '<unknown>'
    [1104, 1112) '<unknown>'
    [1136, 1144) '<unknown>'
    [1168, 1176) '<unknown>'
    [1200, 1208) '<unknown>'
    [1232, 1240) '<unknown>'
    [1264, 1272) 'py' (line 292)
    [1296, 1304) '<unknown>'
    [1328, 1336) 'parser' (line 319)
    [1360, 1368) '<unknown>'
    [1392, 1400) 'helpOption' (line 321)
    [1424, 1432) 'versionOption' (line 322)
    [1456, 1464) 'tempfile' (line 324)
    [1488, 1496) '<unknown>'
    [1520, 1528) '<unknown>'
    [1552, 1560) '<unknown>'
    [1584, 1592) '<unknown>'
    [1616, 1624) 'targetcontrol' (line 328)
    [1648, 1656) '<unknown>'
    [1680, 1688) '<unknown>'
    [1712, 1720) '<unknown>'
    [1744, 1752) '<unknown>'
    [1776, 1784) 'replayhost' (line 333)
    [1808, 1816) '<unknown>'
    [1840, 1848) '<unknown>'
    [1872, 1880) '<unknown>'
    [1904, 1912) '<unknown>'
    [1936, 1944) 'python' (line 337)
    [1968, 1976) '<unknown>'
    [2000, 2008) '<unknown>'
    [2032, 2040) '<unknown>'
    [2064, 2072) '<unknown>'
    [2096, 2104) 'uiscript' (line 342)
    [2128, 2136) '<unknown>'
    [2160, 2168) '<unknown>'
    [2192, 2200) '<unknown>'
    [2224, 2232) '<unknown>'
    [2256, 2264) 'installLayer' (line 348)
    [2288, 2296) '<unknown>'
    [2320, 2328) '<unknown>'
    [2352, 2360) '<unknown>'
    [2384, 2392) '<unknown>'
    [2416, 2424) 'updateFailed' (line 352)
    [2448, 2456) '<unknown>'
    [2480, 2488) '<unknown>'
    [2512, 2520) '<unknown>'
    [2544, 2552) '<unknown>'
    [2576, 2584) 'updateDone' (line 356)
    [2608, 2616) '<unknown>'
    [2640, 2648) 'crashReport' (line 360)
    [2672, 2680) '<unknown>'
    [2704, 2712) '<unknown>'
    [2736, 2744) '<unknown>'
    [2768, 2776) '<unknown>'
    [2800, 2808) '<unknown>'
    [2832, 2840) '<unknown>'
    [2864, 2872) '<unknown>'
    [2896, 2904) '<unknown>'
    [2928, 2936) '<unknown>'
    [2960, 2968) '<unknown>'
    [2992, 3000) '<unknown>'
    [3024, 3032) '<unknown>'
    [3056, 3064) '<unknown>'
    [3088, 3096) '<unknown>'
    [3120, 3128) '<unknown>'
    [3152, 3160) '<unknown>'
    [3184, 3192) '<unknown>'
    [3216, 3224) 'remoteHost' (line 413)
    [3248, 3256) 'regexp' (line 418)
    [3280, 3288) '<unknown>'
    [3312, 3320) 'match' (line 420)
    [3344, 3352) '<unknown>'
    [3376, 3384) '<unknown>'
    [3408, 3416) 'host' (line 428)
    [3440, 3448) '<unknown>'
    [3472, 3480) '<unknown>'
    [3504, 3512) '<unknown>'
    [3536, 3544) '<unknown>'
    [3568, 3576) 'crashReportPath' (line 459)
    [3600, 3608) '<unknown>'
    [3632, 3640) 'uiscriptFile' (line 463)
    [3664, 3672) '<unknown>'
    [3696, 3704) 'pyscripts' (line 467)
    [3728, 3736) 'remaining' (line 470)
    [3760, 3768) 'filename' (line 472)
    [3792, 3800) 'checkFile' (line 476)
    [3824, 3832) 'configPath' (line 491)
    [3856, 3864) 'dir' (line 492)
    [3888, 3896) 'configFilename' (line 498)
    [3920, 3928) '<unknown>'
    [3952, 3960) '<unknown>'
    [3984, 3992) '<unknown>'
    [4016, 4024) '<unknown>'
    [4048, 4056) '<unknown>'
    [4080, 4088) '<unknown>'
    [4112, 4120) '<unknown>'
    [4144, 4152) '<unknown>'
    [4176, 4184) '<unknown>'
    [4208, 4216) '<unknown>'
    [4240, 4248) 'homePath' (line 555)
    [4272, 4280) 'fn' (line 559)
    [4304, 4312) '<unknown>'
    [4336, 4344) 'vkconfigcheck1' (line 562)
    [4368, 4376) '<unknown>'
    [4400, 4408) '<unknown>'
    [4432, 4440) 'vkconfigcheck2' (line 563)
    [4464, 4472) '<unknown>'
    [4496, 4504) '<unknown>'
    [4528, 4536) '<unknown>'
    [4560, 4568) '<unknown>'
    [4592, 4600) '<unknown>'
    [4624, 4632) '<unknown>'
    [4656, 4664) '<unknown>'
    [4688, 4696) '<unknown>'
    [4720, 4728) '<unknown>'
    [4752, 4760) 'warning' (line 587)
    [4784, 4792) '<unknown>'
    [4816, 4824) '<unknown>'
    [4848, 4856) '<unknown>'
    [4880, 4888) '<unknown>'
    [4912, 4920) '__for_begin' (line 601)
    [4944, 4952) '__for_end' (line 601)
    [4976, 4984) 'json' (line 618)
    [5008, 5016) '<unknown>'
    [5040, 5048) '<unknown>'
    [5072, 5080) '<unknown>'
    [5104, 5112) '<unknown>'
    [5136, 5144) '<unknown>'
    [5168, 5176) 'value' (line 652)
    [5200, 5208) 'value' (line 657)
    [5232, 5240) '<unknown>'
    [5264, 5272) '<unknown>'
    [5296, 5304) '<unknown>'
    [5328, 5336) '<unknown>'
    [5360, 5368) 'py' (line 671)
    [5392, 5400) '<unknown>'
    [5424, 5432) '<unknown>'
    [5456, 5464) '__for_begin' (line 708)
    [5488, 5496) '__for_end' (line 708)
    [5520, 5528) 'checkFile' (line 710)
    [5552, 5560) '<unknown>'
    [5584, 5592) '<unknown>'
    [5616, 5624) '<unknown>'
    [5648, 5656) '<unknown>'
    [5680, 5688) '<unknown>'
    [5712, 5728) 'application' (line 284)
    [5744, 5760) 'application' (line 317)
    [5776, 5792) 'f' (line 621)
    [5808, 5832) 'hosts' (line 513)
    [5872, 5896) 'env' (line 580)
    [5936, 5960) 'coreargs' (line 598)
    [6000, 6032) '<unknown>'
    [6064, 6096) '<unknown>'
    [6128, 6160) '<unknown>'
    [6192, 6224) '<unknown>'
    [6256, 6288) '<unknown>'
    [6320, 6352) '<unknown>'
    [6384, 6416) '<unknown>'
    [6448, 6480) '<unknown>'
    [6512, 6544) '<unknown>'
    [6576, 6608) '<unknown>'
    [6640, 6672) '<unknown>'
    [6704, 6736) '<unknown>'
    [6768, 6800) '<unknown>'
    [6832, 6864) '<unknown>'
    [6896, 7032) 'dialog' (line 629)
    [7104, 7120) '<unknown>'
    [7136, 7160) 'errorLog' (line 289)
    [7200, 7224) '<unknown>'
    [7264, 7288) '<unknown>'
    [7328, 7352) '<unknown>'
    [7392, 7416) '<unknown>'
    [7456, 7480) '<unknown>'
    [7520, 7544) '<unknown>'
    [7584, 7608) 'replayHost' (line 512)
    [7648, 7672) '<unknown>'
    [7712, 7736) '<unknown>'
    [7776, 7800) '<unknown>'
    [7840, 7864) '<unknown>'
    [7904, 8016) 'logbuf' (line 255)
    [8048, 8320) 'logstream' (line 256)
    [8384, 8784) 'session' (line 264)
    [8848, 9616) 'config' (line 488)
    [9744, 11352) 'ctx' (line 645)
    [11488, 11509) 'env_set' (line 206) <== Memory access at offset 11504 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope /usr/src/debug/gcc/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:391 in strlen
Shadow bytes around the buggy address:
  0x7fad55b1aa00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fad55b1aa80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fad55b1ab00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fad55b1ab80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fad55b1ac00: 00 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f2
=>0x7fad55b1ac80: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f8 f8[f8]f3
  0x7fad55b1ad00: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fad55b1ad80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fad55b1ae00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fad55b1ae80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fad55b1af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==186532==ABORTING

Setting QT_QPA_PLATFORM with putenv from a local variable
causes the environment to later still refer to it when it's out of scope.
Use setenv instead, as it copies the values provided.
@baldurk baldurk merged commit a0e52fe into baldurk:v1.x Feb 5, 2025
16 checks passed
@Smjert Smjert deleted the fix/asan-qgetenv-crash branch February 5, 2025 16:32
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 30, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants