bullet3
bullet3 copied to clipboard
ERROR: global-buffer-overflow for test_invdyn_bullet.cpp
Bug Report
Environment
- OS Version: Ubuntu 20.04
- bullet3 version: e9c461b0ace140d5c73972760781d94b7b5eee53
- Compiler name and version number: Ubuntu clang 10.0
Description
- Expected behavior: executing code doesn't crash
- Actual behavior: a global-buffer-overflow problem occurs
Steps to reproduce
When testing test_invdyn_bullet.cpp, assertion failure and memory overflow errors occurred. The memory overflow error needs to be an intermittent segmentation fault.
/// create a bullet btMultiBody model of a tree structured multibody system,
/// convert that model to a MultiBodyTree model.
/// Then - run inverse dynamics on random input data (q, u, dot_u) to get forces
/// - run forward dynamics on (q,u, forces) to get accelerations
/// - compare input accelerations to inverse dynamics to output from forward dynamics
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <string>
#include <btBulletDynamicsCommon.h>
#include <btMultiBodyTreeCreator.hpp>
#include <BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h>
#include <BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h>
#include <BulletDynamics/Featherstone/btMultiBodyPoint2Point.h>
#include <BulletDynamics/Featherstone/btMultiBodyLinkCollider.h>
#include <gtest/gtest.h>
#include "../../examples/CommonInterfaces/CommonGUIHelperInterface.h"
#include "../../examples/Importers/ImportURDFDemo/BulletUrdfImporter.h"
#include "../../examples/Importers/ImportURDFDemo/URDF2Bullet.h"
#include "../../examples/Importers/ImportURDFDemo/MyMultiBodyCreator.h"
#include "../../examples/Importers/ImportURDFDemo/URDF2Bullet.h"
#include "../../examples/Utils/b3ResourcePath.h"
#include <invdyn_bullet_comparison.hpp>
#include <btMultiBodyFromURDF.hpp>
#include <MultiBodyTreeCreator.hpp>
#include <MultiBodyTreeDebugGraph.hpp>
#include "Bullet3Common/b3CommandLineArgs.h"
#include "Bullet3Common/b3Random.h"
using namespace btInverseDynamics;
bool FLAGS_verbose = false;
static btVector3 gravity(0, 0, -10);
static const bool kBaseFixed = false;
static const char kUrdfFile[] = "r2d2.urdf";
/// this test loads the a urdf model with fixed, floating, prismatic and rotational joints,
/// converts in to an inverse dynamics model and compares forward to inverse dynamics for
/// random input
TEST(InvDynCompare, bulletUrdfR2D2)
{
MyBtMultiBodyFromURDF mb_load(gravity, kBaseFixed);
char relativeFileName[1024];
ASSERT_TRUE(b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, 1024,0));
mb_load.setFileName(relativeFileName);
mb_load.init();
btMultiBodyTreeCreator id_creator;
btMultiBody *btmb = mb_load.getBtMultiBody();
ASSERT_EQ(id_creator.createFromBtMultiBody(btmb), 0);
MultiBodyTree *id_tree = CreateMultiBodyTree(id_creator);
ASSERT_EQ(0x0 != id_tree, true);
vecx q(id_tree->numDoFs());
vecx u(id_tree->numDoFs());
vecx dot_u(id_tree->numDoFs());
vecx joint_forces(id_tree->numDoFs());
const int kNLoops = 10;
double max_pos_error = 0;
double max_acc_error = 0;
b3Srand(0);
for (int loop = 0; loop < kNLoops; loop++)
{
for (int i = 0; i < q.size(); i++)
{
q(i) = b3RandRange(-B3_PI, B3_PI);
u(i) = b3RandRange(-B3_PI, B3_PI);
dot_u(i) = b3RandRange(-B3_PI, B3_PI);
}
double pos_error;
double acc_error;
btmb->clearForcesAndTorques();
id_tree->clearAllUserForcesAndMoments();
// call inverse dynamics once, to get global position & velocity of root body
// (fixed, so q, u, dot_u arbitrary)
EXPECT_EQ(id_tree->calculateInverseDynamics(q, u, dot_u, &joint_forces), 0);
EXPECT_EQ(compareInverseAndForwardDynamics(q, u, dot_u, gravity, FLAGS_verbose, btmb, id_tree,
&pos_error, &acc_error),
0);
if (pos_error > max_pos_error)
{
max_pos_error = pos_error;
}
if (acc_error > max_acc_error)
{
max_acc_error = acc_error;
}
}
if (FLAGS_verbose)
{
printf("max_pos_error= %e\n", max_pos_error);
printf("max_acc_error= %e\n", max_acc_error);
}
EXPECT_LT(max_pos_error, std::numeric_limits<idScalar>::epsilon() * 1e4);
EXPECT_LT(max_acc_error, std::numeric_limits<idScalar>::epsilon() * 1e5);
}
int main(int argc, char **argv)
{
b3CommandLineArgs myArgs(argc, argv);
FLAGS_verbose = myArgs.CheckCmdLineFlag("verbose");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Output
Here is what the output shows:
/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111: Failure
Value of: b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, autofuzz30,0)
Actual: false
Expected: true
#268 REDUCE cov: 774 ft: 869 corp: 19/2157b lim: 4096 exec/s: 0 rss: 94Mb L: 118/272 MS: 1 CustomCrossOver-
/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111: Failure
Value of: b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, autofuzz30,0)
Actual: false
Expected: true
/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111: Failure
Value of: b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, autofuzz30,0)
Actual: false
Expected: true
/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111: Failure
Value of: b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, autofuzz30,0)
Actual: false
Expected: true
=================================================================
==1070050==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000010c642a at pc 0x0000005ee6be bp 0x7fff6c1ebdd0 sp 0x7fff6c1eb590
READ of size 11 at 0x0000010c642a thread T0
#0 0x5ee6bd in fopen (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x5ee6bd)
#1 0x661c7e in b3FileUtils::findFile(char const*, char*, int) /root/UTopia/exp/bullet3/test/InverseDynamics/../../src/Bullet3Common/b3FileUtils.h:21:7
#2 0x6621c3 in b3ResourcePath::findResourcePath(char const*, char*, int, bool (*)(void*, char const*, char*, int), void*) /root/UTopia/exp/bullet3/examples/Utils/b3ResourcePath.cpp:104:13
#3 0x64b9ac in InvDynCompare_bulletUrdfR2D2_Test::TestBody() /root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:111:2
#4 0x650e75 in enterAutofuzz::AutofuzzTest::runTest() /root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:203:9
#5 0x650a6c in enterAutofuzz /root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:214:10
#6 0xd9e2b6 in TestOneProtoInput(AutoFuzz::FuzzArgsProfile const&) /root/UTopia/exp/bullet3/test/InverseDynamics/fuzz_entry.cc:91:3
#7 0xd9d9cc in LLVMFuzzerTestOneInput /root/UTopia/exp/bullet3/test/InverseDynamics/fuzz_entry.cc:59:1
#8 0x553081 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x553081)
#9 0x5527c5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x5527c5)
#10 0x554a67 in fuzzer::Fuzzer::MutateAndTestOne() (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x554a67)
#11 0x555765 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x555765)
#12 0x54411e in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x54411e)
#13 0x56cf62 in main (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x56cf62)
#14 0x78edf7ec3082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
#15 0x518e9d in _start (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x518e9d)
0x0000010c642a is located 0 bytes to the right of global variable 'kUrdfFile' defined in '/root/UTopia/exp/bullet3/test/InverseDynamics/test_invdyn_bullet.cpp:100:13' (0x10c6420) of size 10
SUMMARY: AddressSanitizer: global-buffer-overflow (/root/UTopia/exp/bullet3/output/fuzzers/InvDynCompare_bulletUrdfR2D2_Test+0x5ee6bd) in fopen
Shadow bytes around the buggy address:
0x000080210c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x000080210c40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x000080210c50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x000080210c60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x000080210c70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x000080210c80: 00 00 00 00 00[02]f9 f9 f9 f9 f9 f9 00 00 00 00
0x000080210c90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x000080210ca0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x000080210cb0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x000080210cc0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x000080210cd0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
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
Shadow gap: cc
==1070050==ABORTING
MS: 6 InsertRepeatedBytes-Custom-CustomCrossOver-CopyPart-Custom-CustomCrossOver-; base unit: dc15c9a1e05137db1c07d46f92cefd6312ad73a7
artifact_prefix='./'; Test unit written to ./crash-8dba9035c836f8946291d62e4c90c3632bf27e98