Skip to content

Commit 9ad5aad

Browse files
authored
[All] Security : memory management, destructors and al (sofa-framework#5904)
* fix unchecked fopen() return * Incorrect fwrite return value check - Issue: fwrite() returns number of items written, not bytes. Comparison was incorrect. - Fix: Changed comparisons from == sizeof(DDSHeader) and == getImageSize() to == 1 * fix potential command injection with sanity check * fix thread safety by replacing volatile with std::atomic * polymorphic base classes were missing virtual destructors - this could cause undefined behavior when deleting derived objects through base pointers * Replace raw new/delete with smart pointers and vectors, and fix memory leak in debug file * fix test of pointer and test ftell result * add a new file to harden code, and move function to escape strings * fix deletion of index which is not an C-array anymore * fix compilation * fix linking
1 parent b424801 commit 9ad5aad

File tree

15 files changed

+72
-39
lines changed

15 files changed

+72
-39
lines changed

Sofa/Component/Constraint/Lagrangian/Model/src/sofa/component/constraint/lagrangian/model/BaseContactLagrangianConstraint.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace sofa::component::constraint::lagrangian::model
4040
// Every ContactParams should implement hasTangentialComponent
4141
struct BaseContactParams
4242
{
43+
virtual ~BaseContactParams() = default;
4344
virtual bool hasTangentialComponent() const = 0;
4445
};
4546

Sofa/Component/Mapping/NonLinear/src/sofa/component/mapping/nonlinear/DistanceFromTargetMapping.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class DistanceFromTargetMappingInternalData
4343

4444
struct BaseDistanceFromTargetMapping
4545
{
46+
virtual ~BaseDistanceFromTargetMapping() = default;
4647
virtual void updateTarget( unsigned index, SReal x, SReal y, SReal z ) = 0;
4748
};
4849

Sofa/GL/src/sofa/gl/VideoRecorderFFMPEG.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <sofa/helper/system/FileSystem.h>
3232
using sofa::helper::system::FileSystem;
3333
#include <sofa/helper/Utils.h>
34+
#include <sofa/type/hardening.h>
3435

3536
namespace sofa::gl
3637
{
@@ -114,7 +115,7 @@ bool VideoRecorderFFMPEG::init(const std::string& ffmpeg_exec_filepath, const st
114115
<< " -pix_fmt " << codec // yuv420p " // " yuv444p "
115116
<< " -crf 17 "
116117
<< " -vf vflip "
117-
<< "\"" << m_filename << "\""; // @TODO C++14 : replace with std::quoted
118+
<< "\"" << sofa::type::hardening::escapeForShell(m_filename) << "\"";
118119

119120
const std::string& command_line = ss.str();
120121

Sofa/GUI/Common/src/sofa/gui/common/ArgumentParser.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,21 @@ void ArgumentParser::parse()
8181
// the original argv and argc
8282
// TODO: upgrade cxxopts to v3 and remove this copy
8383

84-
// copy argv into a temporary
85-
char** copyArgv = new char* [m_argc + 1];
86-
for (int i = 0; i < m_argc; i++) {
87-
const size_t len = strlen(m_argv[i]) + 1;
88-
copyArgv[i] = new char[len];
89-
strncpy(copyArgv[i], m_argv[i], len);
90-
copyArgv[i][len - 1] = '\0';
84+
// copy argv into a vector (automatic cleanup via RAII)
85+
std::vector<std::string> argStrings;
86+
argStrings.reserve(m_argc);
87+
for (int i = 0; i < m_argc; i++)
88+
{
89+
argStrings.emplace_back(m_argv[i]);
90+
}
91+
92+
// build char* array pointing to the strings
93+
std::vector<char*> copyArgv;
94+
copyArgv.reserve(m_argc + 1);
95+
for (auto& s : argStrings) {
96+
copyArgv.push_back(s.data());
9197
}
92-
copyArgv[m_argc] = nullptr;
98+
copyArgv.push_back(nullptr);
9399

94100
int copyArgc = m_argc;
95101

@@ -98,7 +104,7 @@ void ArgumentParser::parse()
98104
{
99105
extra.clear();
100106
m_options.parse_positional("input-file");
101-
const auto temp = m_options.parse(copyArgc, copyArgv);
107+
const auto temp = m_options.parse(copyArgc, copyArgv.data());
102108
vecArg = temp.arguments();
103109
}
104110
catch (const cxxopts::exceptions::exception& e)
@@ -122,12 +128,6 @@ void ArgumentParser::parse()
122128
}
123129
}
124130
}
125-
126-
// delete argv copy
127-
for (int i = 0; i < m_argc; i++) {
128-
delete[] copyArgv[i];
129-
}
130-
delete[] copyArgv;
131131
}
132132

133133
void ArgumentParser::showArgs()

Sofa/framework/Helper/src/sofa/helper/io/ImageDDS.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,8 @@ bool ImageDDS::save(std::string filename, int)
448448
}
449449

450450
bool isWriteOk = true;
451-
isWriteOk = isWriteOk && fwrite(&header, sizeof(DDSHeader), 1, file) == sizeof(DDSHeader);
452-
isWriteOk = isWriteOk && fwrite(getPixels(), getImageSize(), 1, file) == getImageSize();
451+
isWriteOk = isWriteOk && fwrite(&header, sizeof(DDSHeader), 1, file) == 1;
452+
isWriteOk = isWriteOk && fwrite(getPixels(), getImageSize(), 1, file) == 1;
453453
fclose(file);
454454
if (!isWriteOk)
455455
{

Sofa/framework/Helper/src/sofa/helper/system/SetDirectory.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#endif
3434
#include <cstring>
3535
#include <iostream>
36+
#include <memory>
3637

3738
#include <sofa/helper/logging/Messaging.h>
3839

@@ -192,18 +193,15 @@ std::string SetDirectory::GetProcessFullPath(const char* filename)
192193
#elif defined (__APPLE__)
193194
if (!filename || filename[0]!='/')
194195
{
195-
char* path = new char[4096];
196-
uint32_t size;
197-
if ( _NSGetExecutablePath( path, &size ) != 0)
196+
uint32_t size = 4096;
197+
std::unique_ptr<char[]> path(new char[size]);
198+
if ( _NSGetExecutablePath( path.get(), &size ) != 0)
198199
{
199200
//realloc
200-
delete [] path;
201-
path = new char[size];
202-
_NSGetExecutablePath( path, &size );
201+
path.reset(new char[size]);
202+
_NSGetExecutablePath( path.get(), &size );
203203
}
204-
std::string finalPath(path);
205-
delete [] path;
206-
return finalPath;
204+
return std::string(path.get());
207205
}
208206
#endif
209207

Sofa/framework/Helper/src/sofa/helper/system/thread/CircularQueue.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ class SOFA_HELPER_API OneThreadPerEnd
151151
template<class T, class OutputIterator>
152152
unsigned pop(T array[], unsigned maxSize, unsigned maxCapacity, OutputIterator out, unsigned outmaxsize, bool clear = true);
153153

154-
volatile unsigned head;
155-
volatile unsigned tail;
154+
std::atomic<unsigned> head;
155+
std::atomic<unsigned> tail;
156156
};
157157

158158
/**

Sofa/framework/Helper/src/sofa/helper/system/thread/debug.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ TraceProfile::TraceProfile(const char *name, int index, int size)
9595
TraceProfile::~TraceProfile()
9696
{
9797
delete[] name;
98+
delete[] times;
9899
}
99100

100101
void TraceProfile::addTime(int instant, int time)

Sofa/framework/Simulation/Core/src/sofa/simulation/task/DefaultTaskScheduler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class SOFA_SIMULATION_CORE_API DefaultTaskScheduler : public TaskScheduler
124124

125125
unsigned m_workerThreadCount;
126126

127-
volatile bool m_workerThreadsIdle;
127+
std::atomic<bool> m_workerThreadsIdle;
128128

129129
bool m_isClosing;
130130

Sofa/framework/Simulation/Core/src/sofa/simulation/task/Task.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ class SOFA_SIMULATION_CORE_API Task
4545
class SOFA_SIMULATION_CORE_API Allocator
4646
{
4747
public:
48+
virtual ~Allocator() = default;
4849
virtual void* allocate(std::size_t sz) = 0;
49-
50+
5051
virtual void free(void* ptr, std::size_t sz) = 0;
5152
};
5253

0 commit comments

Comments
 (0)