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

Uncaught Exception in PCLPointCloud2::at When Parsing Malformed PLY Files (Potential DoS Vulnerability) #6162

Open
cla7aye15I4nd opened this issue Nov 3, 2024 · 3 comments
Labels

Comments

@cla7aye15I4nd
Copy link

Description:

While parsing certain malformed PLY files, PCL version 1.14.1 crashes due to an uncaught std::out_of_range exception in PCLPointCloud2::at. This issue could potentially be exploited to cause a denial-of-service (DoS) attack when processing untrusted PLY files.

Steps to Reproduce:

  1. Build Environment:

    • Use the OSS-Fuzz configuration to build PCL 1.14.1.
    • Ensure all dependencies are correctly installed.
  2. Run the Fuzzer with Malformed Input:

    • Execute the ply_reader_fuzzer with a malformed PLY file that triggers the crash.

    • Example command:
      poc-pcl

      ./ply_reader_fuzzer /path/to/malformed_ply_file

Observed Behavior:

libc++abi: terminating with uncaught exception of type std::out_of_range: PCLPointCloud2::at
==683== ERROR: libFuzzer: deadly signal
    #0 0x53a191 in __sanitizer_print_stack_trace /src/llvm-project/compiler-rt/lib/asan/asan_stack.cpp:87:3
    #1 0x458ca8 in fuzzer::PrintStackTrace() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtil.cpp:210:5
    #2 0x43d983 in fuzzer::Fuzzer::CrashCallback() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:233:3
    #3 0x7f1f8fa9e41f  (/lib/x86_64-linux-gnu/libpthread.so.0+0x1441f) (BuildId: 0c044ba611aeeeaebb8374e660061f341ebc0bac)
    #4 0x7f1f8f8b000a in raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300a) (BuildId: eebe5d5f4b608b8a53ec446b63981bba373ca0ca)
    #5 0x7f1f8f88f858 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x22858) (BuildId: eebe5d5f4b608b8a53ec446b63981bba373ca0ca)
    #6 0x729d95 in abort_message (/out/ply_reader_fuzzer+0x729d95)
    #7 0x73266e in demangling_terminate_handler() cxa_default_handlers.cpp
    #8 0x729812 in std::__terminate(void (*)()) (/out/ply_reader_fuzzer+0x729812)
    #9 0x72b5d5 in __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) cxa_exception.cpp
    #10 0x72b56f in __cxa_throw (/out/ply_reader_fuzzer+0x72b56f)
    #11 0x5b8266 in float& pcl::PCLPointCloud2::at<float>(unsigned int const&, unsigned int const&) /src/pcl/common/include/pcl/PCLPointCloud2.h:114:9
    #12 0x5b8266 in pcl::PLYReader::vertexIntensityCallback(unsigned char) /src/pcl/io/src/ply_io.cpp:412:11
    #13 0x5b8266 in std::__1::function<void (unsigned char)> pcl::PLYReader::scalarPropertyDefinitionCallback<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_21::operator()(unsigned char) const /src/pcl/io/src/ply_io.cpp:219:57
    #14 0x5b8266 in decltype(static_cast<unsigned char>(fp)(static_cast<unsigned char>(fp0))) std::__1::__invoke<std::__1::function<void (unsigned char)> pcl::PLYReader::scalarPropertyDefinitionCallback<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_21&, unsigned char>(unsigned char&&, unsigned char&&) /usr/local/bin/../include/c++/v1/type_traits:3592:23
    #15 0x5b8266 in void std::__1::__invoke_void_return_wrapper<void, true>::__call<std::__1::function<void (unsigned char)> pcl::PLYReader::scalarPropertyDefinitionCallback<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_21&, unsigned char>(std::__1::function<void (unsigned char)> pcl::PLYReader::scalarPropertyDefinitionCallback<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_21&, unsigned char&&) /usr/local/bin/../include/c++/v1/__functional/invoke.h:61:9
    #16 0x5b8266 in std::__1::__function::__alloc_func<std::__1::function<void (unsigned char)> pcl::PLYReader::scalarPropertyDefinitionCallback<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_21, std::__1::allocator<std::__1::function<void (unsigned char)> pcl::PLYReader::scalarPropertyDefinitionCallback<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_21>, void (unsigned char)>::operator()(unsigned char&&) /usr/local/bin/../include/c++/v1/__functional/function.h:181:16
    #17 0x5b8266 in std::__1::__function::__func<std::__1::function<void (unsigned char)> pcl::PLYReader::scalarPropertyDefinitionCallback<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_21, std::__1::allocator<std::__1::function<void (unsigned char)> pcl::PLYReader::scalarPropertyDefinitionCallback<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_21>, void (unsigned char)>::operator()(unsigned char&&) /usr/local/bin/../include/c++/v1/__functional/function.h:355:12
    #18 0x64878a in std::__1::__function::__value_func<void (unsigned char)>::operator()(unsigned char&&) const /usr/local/bin/../include/c++/v1/__functional/function.h:508:16
    #19 0x64878a in std::__1::function<void (unsigned char)>::operator()(unsigned char) const /usr/local/bin/../include/c++/v1/__functional/function.h:1185:12
    #20 0x64878a in bool pcl::io::ply::ply_parser::parse_scalar_property<unsigned char>(int, std::__1::basic_istream<char, std::__1::char_traits<char> >&, pcl::io::ply::ply_parser::scalar_property_callback_type<unsigned char>::type const&) /src/pcl/io/include/pcl/io/ply/ply_parser.h:586:5
    #21 0x5ef603 in pcl::io::ply::ply_parser::parse(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /src/pcl/io/src/ply/ply_parser.cpp:520:23
    #22 0x57ce91 in pcl::PLYReader::parse(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /src/pcl/io/src/ply_io.cpp:546:21
    #23 0x57d8f9 in pcl::PLYReader::readHeader(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, pcl::PCLPointCloud2&, Eigen::Matrix<float, 4, 1, 0, 4, 1>&, Eigen::Quaternion<float, 0>&, int&, int&, unsigned int&, int) /src/pcl/io/src/ply_io.cpp:563:8
    #24 0x57dcdb in pcl::PLYReader::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, pcl::PCLPointCloud2&, Eigen::Matrix<float, 4, 1, 0, 4, 1>&, Eigen::Quaternion<float, 0>&, int&, int) /src/pcl/io/src/ply_io.cpp:587:13
    #25 0x56e1ae in pcl::PLYReader::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, pcl::PCLPointCloud2&, int) /src/pcl/io/include/pcl/io/ply_io.h:171:16
    #26 0x56e1ae in LLVMFuzzerTestOneInput /src/pcl/test/fuzz/ply_reader_fuzzer.cpp:20:12
    #27 0x43ef23 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
    #28 0x42a682 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
    #29 0x42ff2c in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
    #30 0x459462 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #31 0x7f1f8f891082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: eebe5d5f4b608b8a53ec446b63981bba373ca0ca)
    #32 0x42084d in _start (/out/ply_reader_fuzzer+0x42084d)

NOTE: libFuzzer has rudimentary signal handlers.
@cla7aye15I4nd cla7aye15I4nd added kind: bug Type of issue status: triage Labels incomplete labels Nov 3, 2024
@mvieth
Copy link
Member

mvieth commented Nov 3, 2024

Hi, do you have a PLY file that would cause this behaviour, that you could upload?
Putting the PLYReader::read in a try-catch could be a solution on the user side. But we could also consider adding a try-catch around pcl::io::ply::ply_parser::parse, inside pcl::PLYReader::parse. I am just not sure if it would make sense to try to parse the rest of the PLY file, or simply stop at the first error.

This issue could potentially be exploited to cause a denial-of-service (DoS) attack when processing untrusted PLY files.

Could you explain further what you mean? DoS because the program crashes due to the exception, or DoS due to higher workload?

@mvieth mvieth added module: io and removed status: triage Labels incomplete labels Nov 3, 2024
@cla7aye15I4nd
Copy link
Author

Hello, I have uploaded the file under Example command. It’s in JPG format due to GitHub's file type upload limitations. You can rename it as needed. Additionally, I am referring to a DoS, as the program crashes due to an exception. I am not sure if it should be treated a bug or it is a false positive, but it is indeed considered an error by the fuzzer.

@mvieth
Copy link
Member

mvieth commented Nov 3, 2024

Hello, I have uploaded the file under Example command. It’s in JPG format due to GitHub's file type upload limitations. You can rename it as needed

Got it, thanks 👍 I believe zipping it would also work with the limitations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants