CVE-2021-44961: Slic3r libslic3r PerimeterGenerator Memory Leakage Vulnerability
Published:
CVE Number
CVE-2021-44961
Summary
A memory leakage flaw exists in the class PerimeterGenerator of Slic3r libslic3r 1.3.0 and Master Commit b1a5500. Specially crafted stl files can exhaust available memory. An attacker can provide malicious files to trigger this vulnerability.
Tested Versions
Slic3r libslic3r 1.3.0 Slic3r libslic3r Master Commit b1a5500
Product URLs
https://slic3r.org/
Details
When reading in an .stl
file with the --export-gcode
argument, class PerimeterGenerator
is invoked. The class has some pointers to objects, but it does not provide a destructor and instead uses the default destructor. However, the default destructor only destroys the pointer, but not what the pointer was pointing to. Therefore, the allocated memories are not properly released upon the destruction of class PerimeterGenerator
, leading to potential memory exhaustion.
class PerimeterGenerator {
public:
// Inputs:
const SurfaceCollection* slices;
const ExPolygonCollection* lower_slices;
double layer_height;
int layer_id;
Flow perimeter_flow;
Flow ext_perimeter_flow;
Flow overhang_flow;
Flow solid_infill_flow;
PrintRegionConfig* config;
PrintObjectConfig* object_config;
PrintConfig* print_config;
// Outputs:
ExtrusionEntityCollection* loops;
ExtrusionEntityCollection* gap_fill;
SurfaceCollection* fill_surfaces;
PerimeterGenerator(
// Input:
const SurfaceCollection* slices,
double layer_height,
Flow flow,
PrintRegionConfig* config,
PrintObjectConfig* object_config,
PrintConfig* print_config,
// Output:
// Loops with the external thin walls
ExtrusionEntityCollection* loops,
// Gaps without the thin walls
ExtrusionEntityCollection* gap_fill,
// Infills without the gap fills
SurfaceCollection* fill_surfaces)
: slices(slices), lower_slices(NULL), layer_height(layer_height),
layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow),
overhang_flow(flow), solid_infill_flow(flow),
config(config), object_config(object_config), print_config(print_config),
loops(loops), gap_fill(gap_fill), fill_surfaces(fill_surfaces),
_ext_mm3_per_mm(-1), _mm3_per_mm(-1), _mm3_per_mm_overhang(-1)
{};
void process();
private:
double _ext_mm3_per_mm;
double _mm3_per_mm;
double _mm3_per_mm_overhang;
Polygons _lower_slices_p;
ExtrusionEntityCollection _traverse_loops(const PerimeterGeneratorLoops &loops,
ThickPolylines &thin_walls) const;
ExtrusionEntityCollection _variable_width
(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const;
};
}
Crash Information
Direct leak of 19456 byte(s) in 304 object(s) allocated from:
#0 0x55dca2 in operator new(unsigned long) (/home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/build/slic3r+0x55dca2)
#1 0xe9ef4d in Slic3r::ExtrusionPath::clone() const /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/src/../xs/src/libslic3r/ExtrusionEntity.hpp:77:43
#2 0x69c402 in Slic3r::ExtrusionEntityCollection::append(Slic3r::ExtrusionEntity const&) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:94:37
#3 0x6985fa in Slic3r::ExtrusionEntityCollection::append(std::vector<Slic3r::ExtrusionEntity*, std::allocator<Slic3r::ExtrusionEntity*> > const&) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:101:15
#4 0x697dc8 in Slic3r::ExtrusionEntityCollection::ExtrusionEntityCollection(Slic3r::ExtrusionEntityCollection const&) Direct leak of 19456 byte(s) in 304 object(s) allocated from:
#0 0x55dca2 in operator new(unsigned long) (/home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/build/slic3r+0x55dca2)
#1 0xe9ef4d in Slic3r::ExtrusionPath::clone() const /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/src/../xs/src/libslic3r/ExtrusionEntity.hpp:77:43
#2 0x69c402 in Slic3r::ExtrusionEntityCollection::append(Slic3r::ExtrusionEntity const&) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:94:37
#3 0x6985fa in Slic3r::ExtrusionEntityCollection::append(std::vector<Slic3r::ExtrusionEntity*, std::allocator<Slic3r::ExtrusionEntity*> > const&) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:101:15
#4 0x697dc8 in Slic3r::ExtrusionEntityCollection::ExtrusionEntityCollection(Slic3r::ExtrusionEntityCollection const&) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:11:11
#5 0x69ad9c in Slic3r::ExtrusionEntityCollection::clone() const /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:61:43
#6 0x69c402 in Slic3r::ExtrusionEntityCollection::append(Slic3r::ExtrusionEntity const&) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:94:37
#7 0x1030a22 in Slic3r::PerimeterGenerator::process() /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/PerimeterGenerator.cpp:274:30
#8 0xfe5efd in Slic3r::LayerRegion::make_perimeters(Slic3r::SurfaceCollection const&, Slic3r::SurfaceCollection*) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/LayerRegion.cpp:70:7
#9 0xfd6d81 in Slic3r::Layer::make_perimeters() /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/Layer.cpp:201:24
#10 0xaebb2b in boost::_mfi::mf0<void, Slic3r::Layer>::operator()(Slic3r::Layer*) const /usr/include/boost/bind/mem_fn_template.hpp:49:29
#11 0xaeb921 in void boost::_bi::list1<boost::arg<1> >::operator()<boost::_mfi::mf0<void, Slic3r::Layer>, boost::_bi::list1<Slic3r::Layer* const&> >(boost::_bi::type<void>, boost::_mfi::mf0<void, Slic3r::Layer>&, boost::_bi::list1<Slic3r::Layer* const&>&, int) /usr/include/boost/bind/bind.hpp:253:9
#12 0xaeb796 in void boost::_bi::bind_t<void, boost::_mfi::mf0<void, Slic3r::Layer>, boost::_bi::list1<boost::arg<1> > >::operator()<Slic3r::Layer*>(Slic3r::Layer*&&) /usr/include/boost/bind/bind.hpp:905:16
#13 0xaeaed4 in boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void, boost::_mfi::mf0<void, Slic3r::Layer>, boost::_bi::list1<boost::arg<1> > >, void, Slic3r::Layer*>::invoke(boost::detail::function::function_buffer&, Slic3r::Layer*) /usr/include/boost/function/function_template.hpp:159:11
#14 0xae54fe in boost::function1<void, Slic3r::Layer*>::operator()(Slic3r::Layer*) const /usr/include/boost/function/function_template.hpp:772:14
#15 0xaddf94 in void Slic3r::_parallelize_do<Slic3r::Layer*>(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/src/../xs/src/libslic3r/Fill/../libslic3r.h:119:9
#16 0xae7383 in void boost::_bi::list3<boost::_bi::value<std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*>, boost::_bi::value<boost::mutex*>, boost::_bi::value<boost::function<void (Slic3r::Layer*)> > >::operator()<void (*)(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>), boost::_bi::list0>(boost::_bi::type<void>, void (*&)(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>), boost::_bi::list0&, int) /usr/include/boost/bind/bind.hpp:392:9
#17 0xae70d6 in boost::_bi::bind_t<void, void (*)(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>), boost::_bi::list3<boost::_bi::value<std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*>, boost::_bi::value<boost::mutex*>, boost::_bi::value<boost::function<void (Slic3r::Layer*)> > > >::operator()() /usr/include/boost/bind/bind.hpp:893:16
#18 0xae69be in boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>), boost::_bi::list3<boost::_bi::value<std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*>, boost::_bi::value<boost::mutex*>, boost::_bi::value<boost::function<void (Slic3r::Layer*)> > > > >::run() /usr/include/boost/thread/detail/thread.hpp:116:17
#19 0x1c8b334 in thread_proxy (/home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/build/slic3r+0x1c8b334)/home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:11:11
#5 0x69ad9c in Slic3r::ExtrusionEntityCollection::clone() const /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:61:43
#6 0x69c402 in Slic3r::ExtrusionEntityCollection::append(Slic3r::ExtrusionEntity const&) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/ExtrusionEntityCollection.cpp:94:37
#7 0x1030a22 in Slic3r::PerimeterGenerator::process() /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/PerimeterGenerator.cpp:274:30
#8 0xfe5efd in Slic3r::LayerRegion::make_perimeters(Slic3r::SurfaceCollection const&, Slic3r::SurfaceCollection*) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/LayerRegion.cpp:70:7
#9 0xfd6d81 in Slic3r::Layer::make_perimeters() /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/xs/src/libslic3r/Layer.cpp:201:24
#10 0xaebb2b in boost::_mfi::mf0<void, Slic3r::Layer>::operator()(Slic3r::Layer*) const /usr/include/boost/bind/mem_fn_template.hpp:49:29
#11 0xaeb921 in void boost::_bi::list1<boost::arg<1> >::operator()<boost::_mfi::mf0<void, Slic3r::Layer>, boost::_bi::list1<Slic3r::Layer* const&> >(boost::_bi::type<void>, boost::_mfi::mf0<void, Slic3r::Layer>&, boost::_bi::list1<Slic3r::Layer* const&>&, int) /usr/include/boost/bind/bind.hpp:253:9
#12 0xaeb796 in void boost::_bi::bind_t<void, boost::_mfi::mf0<void, Slic3r::Layer>, boost::_bi::list1<boost::arg<1> > >::operator()<Slic3r::Layer*>(Slic3r::Layer*&&) /usr/include/boost/bind/bind.hpp:905:16
#13 0xaeaed4 in boost::detail::function::void_function_obj_invoker1<boost::_bi::bind_t<void, boost::_mfi::mf0<void, Slic3r::Layer>, boost::_bi::list1<boost::arg<1> > >, void, Slic3r::Layer*>::invoke(boost::detail::function::function_buffer&, Slic3r::Layer*) /usr/include/boost/function/function_template.hpp:159:11
#14 0xae54fe in boost::function1<void, Slic3r::Layer*>::operator()(Slic3r::Layer*) const /usr/include/boost/function/function_template.hpp:772:14
#15 0xaddf94 in void Slic3r::_parallelize_do<Slic3r::Layer*>(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>) /home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/src/../xs/src/libslic3r/Fill/../libslic3r.h:119:9
#16 0xae7383 in void boost::_bi::list3<boost::_bi::value<std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*>, boost::_bi::value<boost::mutex*>, boost::_bi::value<boost::function<void (Slic3r::Layer*)> > >::operator()<void (*)(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>), boost::_bi::list0>(boost::_bi::type<void>, void (*&)(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>), boost::_bi::list0&, int) /usr/include/boost/bind/bind.hpp:392:9
#17 0xae70d6 in boost::_bi::bind_t<void, void (*)(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>), boost::_bi::list3<boost::_bi::value<std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*>, boost::_bi::value<boost::mutex*>, boost::_bi::value<boost::function<void (Slic3r::Layer*)> > > >::operator()() /usr/include/boost/bind/bind.hpp:893:16
#18 0xae69be in boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*, boost::mutex*, boost::function<void (Slic3r::Layer*)>), boost::_bi::list3<boost::_bi::value<std::queue<Slic3r::Layer*, std::deque<Slic3r::Layer*, std::allocator<Slic3r::Layer*> > >*>, boost::_bi::value<boost::mutex*>, boost::_bi::value<boost::function<void (Slic3r::Layer*)> > > > >::run() /usr/include/boost/thread/detail/thread.hpp:116:17
#19 0x1c8b334 in thread_proxy (/home/bug/LabSpace/ins_FuzzerRun/Slic3rFuzzer/build/slic3r+0x1c8b334)
Timeline
2021-11-19 - Vendor Disclosure
2022-01-16 - Public Release
Credit
Discovered by Yuanhaur Chang, Yujie Wang, and Ning Zhang