Last active
December 15, 2025 18:00
-
-
Save Verdagon/4102fecf6dadb7a4802131789b6cc792 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <memory> | |
| #include <variant> | |
| #include <iostream> | |
| struct Engine { | |
| int fuel; | |
| Engine(int fuel_) : fuel(fuel_) {} | |
| }; | |
| struct Spaceship { | |
| std::variant<bool, std::unique_ptr<Engine>> v; | |
| Spaceship(std::variant<bool, std::unique_ptr<Engine>> v_) : | |
| v(std::move(v_)) {} | |
| void print() { | |
| // Print the contents of ship | |
| if (std::holds_alternative<std::unique_ptr<Engine>>(v)) { | |
| auto& engineRef = std::get<std::unique_ptr<Engine>>(v); | |
| std::cout << "Fuel: " << engineRef->fuel << std::endl; // Segfault at address 0x1! | |
| } else if (std::holds_alternative<bool>(v)) { | |
| bool& boolRef = std::get<bool>(v); | |
| std::cout << "Spaceship.v.bool: " << boolRef << std::endl; // Segfault at address 0x1! | |
| } | |
| } | |
| }; | |
| void maintenance(std::shared_ptr<Spaceship> ship) { | |
| // Circuitous shapeshift: changes ship->v to hold Engine pointer | |
| ship->v = std::make_unique<Engine>(Engine{100}); | |
| } | |
| void foo(std::shared_ptr<Spaceship> ship) { | |
| if (std::holds_alternative<bool>(ship->v)) { | |
| bool& boolRef = std::get<bool>(ship->v); // Reference, not pointer! | |
| maintenance(ship); // Changes ship->v to hold Engine pointer | |
| boolRef = true; // Writes to invalid memory through the reference | |
| } | |
| } | |
| int main() { | |
| auto ship = | |
| std::make_shared<Spaceship>( | |
| std::variant<bool, std::unique_ptr<Engine>>{true}); | |
| foo(ship); | |
| ship->print(); | |
| } | |
| // verdagon@Evans-MBP ~ % clang++ -fsanitize=address circshapeshift.cpp && ./a.out | |
| // a.out(27971,0x2027b7ac0) malloc: nano zone abandoned due to inability to reserve vm space. | |
| // ================================================================= | |
| // ==27971==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000001 at pc 0x00010216d770 bp 0x00016dc93050 sp 0x00016dc93048 | |
| // READ of size 4 at 0x602000000001 thread T0 | |
| // #0 0x00010216d76c in Spaceship::print()+0xa4 (a.out:arm64+0x10000176c) | |
| // #1 0x00010216d2c8 in main+0x1cc (a.out:arm64+0x1000012c8) | |
| // #2 0x00019a7220dc (<unknown module>) | |
| // #3 0x5275fffffffffffc (<unknown module>) | |
| // | |
| // 0x602000000001 is located 15 bytes before 16-byte region [0x602000000010,0x602000000020) | |
| // freed by thread T0 here: | |
| // #0 0x0001029a7494 in free+0x70 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x3f494) | |
| // #1 0x00019a6d0c8c in _NXHashRehashToCapacity+0xd0 (libobjc.A.dylib:arm64+0x4c8c) | |
| // #2 0x5b0480019a6d0ba0 (<unknown module>) | |
| // #3 0xe42200019a6eb2c0 (<unknown module>) | |
| // #4 0x750c00019a6eb0dc (<unknown module>) | |
| // #5 0x7e5e00019a6cf7d0 (<unknown module>) | |
| // #6 0x2a7380019a6ce8e8 (<unknown module>) | |
| // #7 0xb35b80019a732d0c (<unknown module>) | |
| // #8 0xaa7980019a72961c (<unknown module>) | |
| // #9 0xa00880019a7304d0 (<unknown module>) | |
| // #10 0xb6a00019a753eb8 (<unknown module>) | |
| // #11 0x491c00019a6ce658 (<unknown module>) | |
| // #12 0x205d80019a8f9724 (<unknown module>) | |
| // #13 0x6a4880019a909178 (<unknown module>) | |
| // #14 0x123f8001a771b63c (<unknown module>) | |
| // #15 0x12500019a73d058 (<unknown module>) | |
| // #16 0x3c0500019a77b304 (<unknown module>) | |
| // #17 0x572680019a76e998 (<unknown module>) | |
| // #18 0x40780019a71e2f8 (<unknown module>) | |
| // #19 0x110d00019a76d92c (<unknown module>) | |
| // #20 0xd26100019a77ae18 (<unknown module>) | |
| // #21 0xb43280019a73906c (<unknown module>) | |
| // #22 0x861e80019a742d24 (<unknown module>) | |
| // #23 0xb41380019a75c358 (<unknown module>) | |
| // #24 0xfc7780019a722f78 (<unknown module>) | |
| // #25 0x806500019a721ed8 (<unknown module>) | |
| // #26 0x5275fffffffffffc (<unknown module>) | |
| // | |
| // previously allocated by thread T0 here: | |
| // #0 0x0001029a7678 in calloc+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x3f678) | |
| // #1 0x00019a6eb234 in NXCreateHashTable+0x6c (libobjc.A.dylib:arm64+0x1f234) | |
| // #2 0x750c00019a6eb0dc (<unknown module>) | |
| // #3 0x7e5e00019a6cf7d0 (<unknown module>) | |
| // #4 0x2a7380019a6ce8e8 (<unknown module>) | |
| // #5 0xb35b80019a732d0c (<unknown module>) | |
| // #6 0xaa7980019a72961c (<unknown module>) | |
| // #7 0xa00880019a7304d0 (<unknown module>) | |
| // #8 0xb6a00019a753eb8 (<unknown module>) | |
| // #9 0x491c00019a6ce658 (<unknown module>) | |
| // #10 0x205d80019a8f9724 (<unknown module>) | |
| // #11 0x6a4880019a909178 (<unknown module>) | |
| // #12 0x123f8001a771b63c (<unknown module>) | |
| // #13 0x12500019a73d058 (<unknown module>) | |
| // #14 0x3c0500019a77b304 (<unknown module>) | |
| // #15 0x572680019a76e998 (<unknown module>) | |
| // #16 0x40780019a71e2f8 (<unknown module>) | |
| // #17 0x110d00019a76d92c (<unknown module>) | |
| // #18 0xd26100019a77ae18 (<unknown module>) | |
| // #19 0xb43280019a73906c (<unknown module>) | |
| // #20 0x861e80019a742d24 (<unknown module>) | |
| // #21 0xb41380019a75c358 (<unknown module>) | |
| // #22 0xfc7780019a722f78 (<unknown module>) | |
| // #23 0x806500019a721ed8 (<unknown module>) | |
| // #24 0x5275fffffffffffc (<unknown module>) | |
| // | |
| // SUMMARY: AddressSanitizer: heap-buffer-overflow (a.out:arm64+0x10000176c) in Spaceship::print()+0xa4 | |
| // Shadow bytes around the buggy address: | |
| // 0x601ffffffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
| // 0x601ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
| // 0x601ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
| // 0x601fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
| // 0x601fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
| // =>0x602000000000:[fa]fa fd fd fa fa fd fd fa fa 00 00 fa fa 00 fa | |
| // 0x602000000080: fa fa 00 04 fa fa fd fd fa fa 00 00 fa fa 04 fa | |
| // 0x602000000100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa | |
| // 0x602000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa | |
| // 0x602000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa | |
| // 0x602000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa | |
| // 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 | |
| // ==27971==ABORTING | |
| // Fuel: zsh: abort ./a.out |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment